Saturday, September 12, 2015

Summit Everest! Surviving the engineering death zone.




The lifecycle of a software product can seem mysteriously vague,  complex, or overly simplified depending on the audience.  I liken it to a climb with the highs, lows, and ultimately a conquest or defeat.

Base Camp

The beginning of a new project and the buzz of fresh energy throughout the team is palpable.  Ideas, roles, and a vision of the possible emerges from every situation or get together. The morale and excitement is at an all time high! Every creature comfort is available and the team starts off as well rested and prepared as they will ever be.

Camp One

Camp one is reached in record time, the time to market forecast is being wildly exceeded as sheer energy and momentum lifts the team seemingly without effort. Prototypes and functionality appear weekly out of nowhere.  Checkins litter the git history from what looks like 24/7 output people trying to write as fast as their brains can think.  Product management is struggling to keep track of all the new work.
   

Camp Two

Camp two is also quickly reached but the renaissance of creativity yields to the thinner air of coalescing effort. Some time is now being spent acclimatizing instead of rapidly moving forward, fewer feature branches appear as product management steers a unified course up the mountain.  Some re-planning and adjustment are implemented.

Camp Three (Lhotse wall)   

Arrival at camp three is signaled by the teams progress velocity returning to real world numbers. It took longer to get here then expected, maybe a lot longer. A unified codebase along with the requisite build and test process has appeared. Creativity is scaled back to solving many of the initial hand waves done earlier in the climb that kept the forward momentum at the expense of problem solving each detail.  Some doldrums will set in and those truly in shape will seem less affected,  leaders may rise and fall here.

Camp Four (The death zone)

You have reached the death zone, this is the 10% of remaining work that will take 90% of the projects total effort to complete.  The go to market schedule which was insanely optimistic and ahead of schedule now suddenly seems to be behind.  The engineering progress as been reduced to a crawl. Any small change in requirements,  code refactoring, or new feature development has wide ranging implications that can tie up the team for days to sort out.  As people sip oxygen from what remains in the tanks it takes supreme confidence and leadership to overcome the fear and exhaustion for the final push to the summit.  Lingering at camp four seems to go on forever,  you must have confidence.

At this point it can sometimes be necessary to bring in finishers to help with the final push. Finishers are fresh eyes and legs that can give some perspective to the team that is not tunnel visioned or snow-blinded from fighting up every inch of the trail to this point,  A fresh perspective can help chart the easiest path to the summit, it can also lead you into an avalanche so the right guide is CRUCIAL.

Summit 

What needs to be said here really, pop a champagne and take a picture. But don't tarry or bask too long on the top of the world its dangerous to do so. Quickly get back down to basecamp to rest and rebuild the team, and begin to prepare for the next climb.

Thursday, June 12, 2014

Google Web Toolkit (GWT) Event Bus

Recently doing some GWT development and wanted to expand an example of the toolkit's event bus.
This contrived example doesn't involve widgets, or UI handling and is only meant to highlight the principle using simple example/pseudo-code. This assumes some knowledge on the internal workings of the GWT Event Bus or observer design pattern, treated as a black box here.

Imagine a virtual restaurant where you have a cook, waiter, and a customer.

The business process is, "The waiter takes the customer's order and gives it to the cook."
In this familiar scenario you have; cook, waiter, order, and customer.

In the GWT Event Bus world you have Events, Event Handlers, and Entities(Widgets, Objects etc).

Mapping to our little scenario thusly.

Events {OrderPlacedEvent}
Event Handler {OrderPlacedEventHandler}
Entity {Waiter, Customer, Order}

The real question is, how to design for an event bus, or, what to design first?

Handlers are used by entities that need to "handle" events.  Our waiter is interacting directly with the customer and so doesn't need to handle an order "event", he's the interface (virtually maybe) taking/constructing the orders. The cook on the other hand is in the kitchen and busy doing non customer related tasks, but he's very interested in orders so he can do his job of making the food.

So, the cook wants to be informed of orders being placed, and what they are, and the waiter will be the one to inform. With the event bus ANYONE can be informed about the order immediately as it's placed, cooks, managers, supply systems, etc.

First thing is to create the Handler. The reason is that the Event will actually need to register the Handler Type in the Event bus, and your Event will also reference it.

/**
 *
 */
public interface OrderPlacedEventHandler extends EventHandler {

     void onOrderPlaced(OrderPlacedEvent event);

}

Now we have a handler interface with a method to invoke with an event IF one occurs.

Next we create OrderPlacedEvent,  but first the order would be helpful.

/**
 *
 */
public class Order{ 

      private List<FoodItems> items;          

      public Order(FoodItems...items){
            items = new ArrayList<>(Arrays.asList(items));
      }

      public List<FoodItems> getItems{
             return this.items; 
      }
      ...
}

The actual Event, conventions as per GWT plus a reference to the order.

/**
 *
 */
public class OrderPlacedEvent extends GwtEvent<OrderPlacedEventHandler>{

       public final Order order;
       public static final Type<OrderPlacedEventHandler> TYPE =
                                     new TYPE<OrderPlacedEventHandler>();

        public OrderPlacedEvent(Order order){
              this.order = order;
        }

        public Order getOrder(){
              return this.order;
        }

       @Override
        public Type<OrderPlacedEventHandler> getAssociatedType() {
              return TYPE;
        }

        @Override
        protected void dispatch(OderPlacedEventHandler handler) {
               handler.onOrderPlaced(this);
        }

}


The cook needs to register the handler and do something with the return value, in this simple case he adds it to the internal list of orders he's working on. The event bus listens for the TYPE to arrive and then iterates through every registered handler calling it's implementation as defined in dispatch.

/**
*
*
*/
public class Cook{

     private List<Order> orders = new ArrayList<>();

     public Cook(EventBus bus){
                eventBus.addHandler(new OrderPlacedEventHandler(){
                                void onOrderPlaced(OrderPlacedEvent event){
                                                   addOrder(event.getOrder);
                                                   }}, OrderPlacedEvent.TYPE);
     }

     public addOrder(Order order){
              orders.add 
     }     
}


Waiter will be the one to "fire off" an order placed event to let everyone know at the end of his order taking process.


/**
 *
 */
public class Waiter{

    private EventBus eventBus;
    
    public Waiter(EventBus eventBus){
            ...

     }

     public void takeFoodOrder(Order order){ 
           ...
         eventBus.fireEvent(new OrderPlacedEvent(order));

      }

}



That's it! Hope it clears up some of the design and workings using this simple scenario.  I highly suggest using the EventBinder when coding in GWT proper instead the classes you see here, does all the same things but it's less coding!






Tuesday, March 4, 2014

This is easy!

Wondering why your software product / project is taking so long or has quality issues, then ask yourself these simple to answer questions.

1. Using an Agile methodology? 

2. Enforcing testing and code review? 

3. Using continuous integration? 

4. Branching and tagging code by development, bug fix, and release versioning? 

Don't waste time trying to figure out what's wrong until you can answer YES to every one of those questions. This is easy until you make it hard. :)