Thursday, March 21, 2013

Going Native

Right now we're in a limbo period because we're waiting to shake out the kinks from our latest release before migrating our source code repository from Subversion to Git - and after that we'll branch the code so maintenance, minor revisions and major revisions can go on simultaneously.

So for the time being we want to keep the source tree clean so we can push quick maintenance releases.  This means that aside from bug fixes for the release, we needed a little side project to keep the team busy.

Picking a Mobile Architecture

The can that always seems to get kicked down the road around here (aside from multi-session) is mobile applications.  We talk about it a lot, it always seems like it's just around the corner, but other things always seemed to take priority.

We did some ground work for mobile as part of the last release in that we introduced Spring-MVC to the server side portion of Flex as a platform for building the REST API we'll need for mobile applications (and for the inevitable HTML 5 interface).

After much debate and hand wringing, last week we started in earnest on a version of Flex for IOS devices (iPhone, iPod Touch, and iPad).  For a long time we'd discussed exactly how to go about this.

Adobe and now the Apache Software Foundation supports tools for building IOS and Android apps in Flex/Flash and compiling them as applications for the native platform.  The reason many people run around saying Flash is dead stems from Adobe's announcement that they would not support Flash on mobile devices, which the technology press and the echo chamber took to mean Adobe isn't supporting Flash at all, which became over the last year or so a kind of self fulfilling reality.  Among those who don't know what HTML 5 actually is - which is most people - Flash is dead.

It may not really be dead, but it's future as a platform for mobile development looks pretty bleak, even though the Apache project that inherited the work from Adobe seems committed to mobile development.  It could have a revival, but at this point it's just too risky.

Another common approach to mobile apps is developing them as web applications, usually with jQuery and a healthy does of Safari extensions and deploying them as IOS apps.  For the user, it launches like a dedicated app, but without all the hassle of learning Cocoa, IOS, and Objective-C.

We thought for a long time that this is what we'd end up doing at Flex.  Then we read about the disaster Facebook's web based mobile app turned into.  If they can't get a fast, reliable mobile app going with all their resources, then little old Flex Rental Solutions doesn't stand a chance.

We also need some hardware support for things like bar code scanning, so we decided to bite the bullet and go native.  The first generation of Flex IOS apps will be written in Objective-C using XCode.  It's a learning curve, to be sure, so far it's going well.

We were able to get from an empty project to a first screen in about a day:


Beyond Bullet Points

Once we got the basic "Hello World" screen up and running, it was time to think about some architectural considerations.  One of the things we talk about a lot here is going beyond the minimum effort required to support a feature bullet point.  A key past example is Quickbooks integration.  Most of our competition has accounting integration, but it's poorly thought out, batch oriented and borderline unusable.  We wanted a form of Quickbooks integration that actually works, so we invested a significant amount of time into fine tuning it.  Roger's done great work here.

By the same token we don't just want iPhone and iPad apps just to tick off the bullet point.  They need to be well thought out and not just clones of our existing interface.  A touch based UI is completely different.  We need to start from scratch and not let our preconceived notions about UI's that come from the Flash world contaminate the mobile project.

The first consideration is login.  It's one of my pet peeves when a mobile application makes me type in my entire username and password every time I launch it.  I want it to just pop right up - or at most prompt me for some kind of pin code I can type easily with my thumbs.

With this in mind, we're designing our IOS apps to support a one time login that generates a set of credentials unique to each device that are then used for accessing data.  This means the app will just pop right up where you left off without forcing you to log back in.  The app will also support multiple Flex servers, meaning you can communicate with multiple Flex servers from the same app - which might be a common use case for freelancers.

With freelancers in mind we'll be introducing in the coming months a limited form of access to Flex where freelancers can see their schedules on the web, accept or decline jobs from the web - without Flash and without creating user accounts for each of them.  These same freelancers will be able to connect their mobile devices to Flex using a device code that they'll receive in an invitation email.

Once connected, they should be able to view their schedules and gig requests direct from the app.

Caching Data Locally

Under the hood, we've decided to take advantage of the IOS platform's ability to store data and cache as much data as possible on the device.  This will speed things up by reducing network communication and enable users to view information even if the network connection is sketchy or dead - key for freelancers who just need to double check call times.

To support this we're adding a version hash code to most elements of the data model.  When a piece of data is loaded on the iPhone, we'll send a refresh request to the server along with the version hash. The server will check this hash against the one it has on file and either send and updated copy of the data or indicate that the phone's data is up to date and no refresh is needed.  For things that seldom change - like pricing models, resource types and project element definitions, this should be a valuable optimization.

Session Controllers

We love the Model-View-Controller pattern at Flex and use it just about everywhere.  In IOS apps, you have no choice but to use it.  The controller in an IOS app starts with something called an Application Delegate - and this can be the controller abstraction for most IOS apps, because most IOS apps are simple and dedicated to one or two basic tasks.  Flex is very complicated, and we needed a way of breaking up the complexity into manageable chunks.

We also need an abstraction that hid the device specific user interface details.  For example, a user interface that might only be one screen on the iPad might be a whole nest of related screens on the smaller iPhone.  We wanted a single controller abstraction that encapsulated all that. 

For that we created a session controller class, the header file of which is shown here:

#import <Foundation/Foundation.h>

@class FRSAppDelegate;

@interface FRSSessionController : NSObject


-(void)launchInitialView:(FRSAppDelegate*) delegate;

-(UIViewController*)launchIPhoneView:(FRSAppDelegate*) delegate;

-(UIViewController*)launchIPadView:(FRSAppDelegate*) delegate;

@end
We have a session controller for account setup and navigation - and will likely create session controllers for warehouse functions, contacts, quotes, inventory management, etc.

 In the application delegate (the root object of an IOS application) we have a method for launching a "session" and setting a reference to the active session controller where user interface code can find it.  The user interface code will use the session controller to retrieve data from the server or send updates to the server, and also as a place for storing data temporarily between screen transitions.

Scanning

Roger's role is in this effort was to test different techniques for scanning bar codes on a mobile device.  There are barcode scanner attachments for IOS devices, but they're expensive and we don't think they'll be very common.  We opted instead to support Bluetooth scanners and scanning via the camera.  Using a library called Red Laser, Roger was able to successfully scan barcodes with the camera and Bluetooth scanning has also been successfully tested on our architecture.

Wrapping Up

In spite of our detour into mobile apps, the focus at Flex right now is server side architecture and speed.  4.6 was a good step regarding speed, but until we have a scalable and fast server side infrastructure, we really can't waste time on other big projects.

We only started work on mobile apps because we were stuck in a little donut hole that prevented us from working on big server side changes.  Even so, with the architectural ground work now laid, work on mobile will continue as opportunities arise and will accelerate once we've stabilized our server side platform.  Chris should have something to tease everyone with at Infocomm and we should have something big to announce at LDI, perhaps even before then.





Friday, March 1, 2013

Next Generation Architecture

Earlier this week, I talked about some of the short term work we're doing to establish performance benchmarks and some of the first steps toward speeding things up.  I also mentioned the issues we have with our instance-per-customer deployment model.  I neglected to mention what our proposed solution is for a long term architecture that provides greater reliability, faster performance and efficiently uses resources, so I thought I'd do a short post to catch every one up on our progress toward the next generation architecture.

In A Nutshell

Over the next twelve months we'll be modifying Flex to support something called multitenancy, which means a single instance of Flex will simultaneously support hundreds of customers.  This will enable us to allocate resources based on customer load or usage.  Instead of having one server for every eleven customers, we'll have a minimum of two servers (for failover) in front of a load balancer and dynamically allocate additional server capacity in response to load.  When the load drops off (overnight, for example) we'll spin down the extra servers.

We also plan on adding some extra special purpose servers for things like report generation, caching, search and indexing and overall control of the cluster.  The diagram shows what we're thinking about doing:



Planning the hardware deployment architecture is always fun, but the bulk of the work will be in the software.  There are a lot of interesting software engineering problems we'll be tackling and none of these problems are unique to Flex; they're common to any traditionally developed back office J2EE application migrating to a cloud based mult-tenant architecture.

The Alto Project

We've already started work on the software part of this problem by creating an open source project dedicated to providing frameworks and utilities J2EE projects will need to move to a mult-tenant efficient cloud architecture.  You can find a summary of the engineering problems we'll be addressing by viewing the project's wiki here:  https://github.com/alto-project/alto/wiki

You can also take a look at the project's source code as it develops and even contribute if you're so inclined.

Two Ways

A unique challenge for our architecture is that we always want to maintain support for the single instance back office model.  Just as there's now a big move to the cloud, who's to say that some years down the road there won't be a move back to self-hosted applications.  This prospect, along with the fact that we do have a fair number of self-hosted or dedicated hosting customers, means we never want our architecture to "force" anyone to be in the cloud.  We need an architecture that works both ways without requiring separate builds for a cloud deployed version or a self-hosted version.  Switching between the two should be configured solely through external JNDI parameters.

So, that's the vision for Flex over the next year or so and a big reason why we feel branching the code is so important.  Work on this next generation architecture is ongoing and will ramp up even more once we've addressed the Hibernate performance bottlenecks.  We need to be doing this work in a code branch that won't impact or slow down ongoing Fast Track projects or routine maintenance.

I, for one, am looking forward to the next twelve months.  I'll get to work on some pretty cool stuff.