Tuesday, March 20, 2012

Auto Refreshing Your UI?

It seems that forever, there's been this battle between building an application that automatically refreshes when data changes or provides the user with a refresh button to press at their leisure. One can see the benefit of both. Let's say your interface is displaying a large graphical map of data that a user has sized, shaped, and customized to their liking. In comes a database update (probably from another user) and the application automatically redraws the graphical map, removing all the customizations that the user has spent time doing. Not good. Maybe lighting up a "refresh to see new data" button would have been better in this case.

Let's say a user is looking at a table of data showing objects and statuses. Due to an event in the system, one of the objects has gone from a green status to red. This is a case where an automatic refresh is in order otherwise how will a user know of this change in condition?

So given different circumstances, multi-user applications, event processing applications and the like, how can I build an application that automatically refreshes. My goal has always been to never have a "refresh" button on my menu bar. Having one, shows an application that has not been architected or designed for ultimate ease of use and an application that some users might find broken or out of date frequently.

Real World Example

Using GWT for my application development, I built a GWT UI server backend that my UI clients connect with asynchronously to "get" and "set" data. A hibernate DB backend server allows my GWT UI server to "get" and "set" data via a REST api. So all the moving parts are nicely in place. A DB storing all the data, a UI server that interfaces with the DB server and provides asynchronous data to any UI client that connects to it.

How to keep a client view auto refreshed?

The first part was to get my UI server in sync with the DB server. In one of my UI views, I show a table to objects, let's call them "widgets". These widgets have a name, description, update date and a status. My UI client will ask my UI server for a list of these objects to then feed into my GWT table. My UI server could make a call over to the DB server to get these objects, but how to keep in sync with changes that can occur and how to make this perform ok?

The Magic.

Upon initial connection and startup, my UI server gets all of the "widgets" from the DB server and stores them. It then starts a timer, going off every second, which ask the DB server via REST, if any of these widgets has changed (created, deleted, modified). For the most part this call returns "nothing to do" and the timer goes back to sleep. However, a key part of this is that my UI server always has the latest data in its data structure and always keeps it up to date (at least within a second or two). If a change does occur, the UI server data structure is updated and a date stamp is created for this update.

Along comes a UI client that connects to the UI server and asks for the widget data for the GWT table. The UI server already has a data structure ready to go and returns the data instantly to the client. The table is drawn. Any other UI clients connecting will get the exact same results. All the UI clients share this UI server. When the UI client has completed populating and displaying the table, it in turn starts a timer. Each time the timer goes off, it asks the UI server if any of the "widgets" have changed. The UI server returns the date stamp of the last change and UI client uses this to determine if it already saw this change or not. If not, the UI clients get the new data and updates the GWT table.

In summary, the UI server's job is to ask the DB server about changes using a timer and keeps the data structure up to date with the DB. The UI client's job is to ask the UI server about any changes it has, also using a timer. Since all UI clients share the same UI server, they are all in sync all the time and all see the same underlying data.

In demoing my application, I always get the comments of "this application is very fast" and "it sees updates very quickly", and of course "why don't all application refresh like this?"

In a future blog, I'll cover this more with some sample code and diagrams. For now, give you users the most usable application you can. Software is great at the mundane tasks....updating data structures!