Errai: The browser as a platform

Friday, November 16, 2012

The Future is Asynchronous!

For the last month or so, I've been hiding in a cave working on a big, upcoming feature in Errai 3.0. Which may sound crazy considering that we have yet to release 2.2 yet. But that's how I roll.

Well, it's more that this is a big feature, and we've feature-frozen Errai 2.2 on its path to productization as part of JBoss's WFK product, of which Errai will be a featured framework next year. So, big new features are bound for 3.0.

So what is this new feature? It is nothing other than the new asynchronous bean manager for Errai IOC/CDI! If you follow me on Twitter (@JBossMike) or on Google+, then you might have stumbled upon the highs and lows of my gargantuan effort to implement this.

First the big questions: what is asynchronous bean management, and why do we need it?

Asynchronous bean management may be an unfortunate term. Perhaps a more accurate name would be asynchronously-loading bean management. But I don't like how that sounds, so... the former it is!

The basic idea behind asynchronous bean management is the idea that the loading, construction and dependency-injectimification (yes, I made that word up) are done asynchronously. Obviously. But what does that mean?

It means that bean loading happens in parallel to your application logic -- the reason why this is desirable will be answered in the 'why' part.

In practice, you make a request to the bean manager for the instance of a bean, it goes and gets the bean (if it's already in existence) or it makes a new instance and gives it to you. But the way it gives the bean to you is through a callback mechanism.

Let's take a look at this in practice:
That's a bit different than what one might be use to if you've used the old bean manager API, where you would instead do this:

The asynchronous version is quite a bit more code!

The difference is, with the asynchronous lookup, the anonymous class we defined -- CreationalCallback  -- is used to receive the bean once its been created by the bean manager. When this happens, the callback() method is called, passing an instance of the bean. You then do something with that bean. In this case, we call it's show() method which, displays the popup widget.

You could imagine this sort of thing getting really out of hand. But really, most direct calls to the bean manager in your app are probably quite rare, and probably something you may already be abstracting away behind say, an Activity and Places pattern -- in which case, this extra code overhead is negligible.

But here's the real question: why?

The answer is: code-splitting!

One of the really cool features of GWT is its ability to partition your code behind runAsync() calls. This means, that as your app grows, you may find that the upfront loading time becomes undesirably long; wouldn't it be nice if the actual code needed was downloaded on-demand, based on the parts of the application which the user is actually using? Well, that's what GWT's code-splitting does!

The problem with synchronous bean loading, is it short-circuits your ability to use GWT's code-splitting effectively if your app is built completely around CDI. This is because Errai emits synchronously executing bootstrapping code to wire you application.

The asynchronous bean manager instead makes all the mechanics of the bean manager internally and externally (as shown above) based completely on a callback pattern. Meaning, quite simply, any aspect of bean management can now be contained in a GWT runAsync() callback. Yay!

Taking our example above as a scenario to contemplate: it may be that we have indicated that the class Popup is a bean we'd like to code-split. Errai 3.0 will allow you to do this by annotating that bean with the @LoadAsync annotation. This means, that all of the code of Popup -- assuming it does not have code paths to and from parts of your app that are needed in the initial application download --  can be segmented into a separate JavaScript payload. So, when we make our asynchronous lookup of this bean for the first time, we are able to download the JavaScript code, create the bean, and pass the loaded bean to you when it's ready!

You might decide, for the size of you app, that you don't need this functionality. Which is fine. We will be retaining both implementations of the bean manager -- the old one is not being deprecated. The caveat is only this: your app will be required to use one or the other. You cannot mix synchronous and asynchronous bean management within a single Errai app. Trust me: it's not possible or practical.

In closing, this is just one of the new amazing features coming in 3.0 which will allow you to take maximum advantage of GWT's performance-optimizing capabilities when using Errai.

I'm hoping to have something people can play with in the coming days. Stay tuned!

1 comment:

  1. Big feature. I have start using Errai for just 1 day :-) but is good to know that this kind of advanced use of GWT code-spliting with errai in the future.

    Very cool!