Tuesday, September 29, 2015

MacBook Pro Display Issue

Just got a new MacBook Pro with Retina display and had a heart attack when 3 days in the display started flashing blue and yellow, almost like a refresh problem.  After resetting the NVRAM (which had no effect on my issue), clearing out bad color profiles, deleting caches, etc, I was ready to head to the Mac store.  Luckily, I tried one last thing which was to disable Automatic Graphics Switching under the Energy Saver system preference.


Once this was disabled I haven't seen the problem since.  Hope this helps someone else!  I imagine this happened after an update was applied, but I have no proof of that.

Wednesday, July 15, 2015

Reminder of Wirebox Dependency Injection Lifecycle

I remember reading it in the Wirebox Ref Card, but I actually ran into an issue with Wirebox dependency injection and a race condition today.  I wanted to blog about it just in case you started with Wirebox without reading the documentation end-to-end ;)

When you are using Wirebox mixin injection to autowire properties, dependencies are not injected until after your pseudo-constructor is called.  Here is an example that will fail:

 component accessors="true" {  
   property name="myDAO" inject="";  
   public function init() {  
     getMyDAO().myMethod();  
   }  
 }  

This will cause an error since myDAO has not been injected into the component before init() is called.  The solution is pretty simple:

 component accessors="true" {  
   property name="myDAO" inject="";  
   public function init () {  
   }  
   public function postInit() onDiComplete {  
    getMyDAO().myMethod();   
   }  
 }

Adding the onDiComplete annotation to the postInit() method tells Wirebox to run the method after it has instantiated the object and injected any dependencies.  I did notice that the method must be public which is unfortunate, but it makes sense.  This simple example is pretty useless, but in my case I needed to store a query into a singleton on instantiation so this was just the ticket.

Thursday, June 25, 2015

Wirebox: Creating a Transient Object in a Service

Today I had the need to create a transient object outside of the normal places Wirebox lives in a Coldbox application (handlers, interceptors, etc).  I come from a ColdSpring background, so I never used CS to handle any of my transients, but I wanted to see how Wirebox handled this so I could keep my object creation centralized.

There are several ways to handle creating a transient object in a ColdFusion service.  The easiest is to use createObject() or create a new object using the new keyword right where you need it like this:

var myObj = createObject("component", "path.to.my.Object");
 -or-
var myObj - new Object();

Another option is to have your service hand you a new object by defining a load() method:

public myObjectType function load () {
  return createObject("component", "path.to.my.Object");
}

The above method works best when using something like CF ORM, where you would specify an optional id parameter and use entityLoadByPK() and return a persistent object.  Overkill for what I need here (no persistence in this application).

What I ended up doing to keep my objects coming from a single source (Wirebox) was to inject Wirebox into my service and use the getInstance() method to hand me a transient instance of my object:

Wirebox.cfc
...
map("myObject").to("path.to.my.Object");
...

Service.cfc
component accessors="true" {
  property name="wb" inject="wirebox";
  ...
  function myFunc () {
    var myObj = getWB().getInstance("myObject");
  }
}

I figure doing it this way makes it much easier as I am presently moving around packages, so defining them once in Wirebox means I don't have to perform a search and replace once the packages settle - I just fix the path in the Wirebox configuration and all objects are updated when the application is reloaded.

Note that this works well for transient objects, but remember for singletons you would just inject them into a property in your service tier.

Tuesday, June 23, 2015

Maildev for Local Development

Recently at work I was tasked with finding a fake SMTP server that would capture emails for review for environments preceding Production. This is especially useful when you are importing production data for testing across environments and ensuring that your customers don't get test emails.  It's something we have all coded around with complex environment configurations in the past, and it offers a much simpler solution.

I looked around at quite a few solutions and most ended up being Windows service based. Being on a Mac they were less than useful, and given that my requirements included the need to move the configuration across multiple environments which are shared by a team of developers, those fell short as none included a web interface for reviewing emails. They all seemed to favor a desktop GUI which could not be viewed without logging in to each server for viewing.

Enter Maildev. Maildev is actively maintained and looks like it has been around for almost year now (probably longer, I'm just going by github commits).

There are a few ways to install, but I installed via npm.  It couldn't be simpler:

  1. Download and install NodeJS/NPM, unless you already have them (as you should!)
  2. Install Maildev using npm (npm install -g maildev).  You'll need to sudo for Mac/Linux.
  3. Start maildev by typing maildev
Pretty straightforward stuff.  Maildev starts on port 1025 by default.  The web interface is available at port 1080.  Maildev will listen on all IPs by default (0.0.0.0).  These are easy to configure using the command line options -s, -w, and --ip.

Installing this across environments permits you to capture emails on each specific environment, and binding Maildev instances to various IPs allows you to isolate email on a per application basis.  If you are on windows you can always install Maildev as a service using nssm.  On Linux you'd use a combination of forever (maybe) and upstart or chkconfig or whatever your flavor permits.  Let's face it, you're on Linux.  You'll figure it out.

Maildev also has some nice features like testing your emails in various viewports and viewing headers and attachments.

For my purposes using ACF or Railo, the mail config was moved to the app configuration and switches across environments using Ant filter tasks triggered by Jenkins.  I'm sure whatever language you are using has a similar simple configuration option to simplify the task.

Kudos to Dan Farrelly for creating such a useful development tool.