Errai: The browser as a platform

Friday, February 17, 2012

Doing things in the right order

A serious problem that we've faced internally in making a framework like Errai work nicely is the sometimes unpredictability of the order in which client-side services initialize. Non-GWT client-side developers working with jQuery often run into a similar problem.

For a long time, we've had various mechanisms to manage this problem. Well, it's really the same mechanism spread across many components -- "post-init" callback events.

It's a good pattern, works good and it's intuitive enough to work with. But with Errai 2.0, we've added a set of new features when working inside Errai IOC/CDI. We lovingly call them "Lifecycle Tools" in our new documentation for them, which you can find here.

It's easy enough to register callbacks and wait to be called back to. But since Errai has heavy emphasis on dependency injection, this problem seemed ripe for a nice, clean, don't-call-us-we'll-call-you approach.

So, when you have a client side bean -- and I use @Singleton here for maximum compatibility if you're not using CDI -- you can merely declare a startup dependency on your component by, well, injecting a startup dependency!



@Singleton

public class MyClientBean {

  @Inject InitBallot<MyClientBean> ballot;



  @PostConstruct

  public void doVote() {

    // do lots of initializy stuff.

    

    ballot.voteForInit();

  }

}



This code ensures that initialization of framework services will need to be delayed until it can do whatever work needs to be done. The parameterizing of the InitBallot is the way in which we categorize the dependency. You don't actually have to use the declaring classname. But the dependency must be unique. For instance InitBallot<Foo> will create a dependency on the class Foo. This is purely symbolic. But if the service fails to dial home with a voteForInit() call, in the bootstrap error message, it will be Foo that will be reported as the failed dependency. So keep that in mind.

Doing Stuff After...

There's of course the other obvious side to this coin. Which is wanting to do things only after you know all the framework services are initialized, happy, and doing their best Elvis dance. This job calls for our latest annotation, lovingly inspired by @PostConstruct, the wonderfully new and shiny @AfterInitialization annotation.

This is about as straight-forward as it gets. You create a method in your bean, and you... annotate it! When all the crazy things Errai does to bootstrap are done (bus federation, rpc proxies loaded, marshallers ready), your method will get called! It works like, and basically has all the same restrictions as @PostConstruct and so you use it like so:



@Singleton

public class MyClientBean {



  @AfterInitialization

  public void doStuffAfterInit() {

    // do lots of after-initialzy stuff!

  }

}



... And there's all there is to it!

The only downside is this feature is not in our 2.0.Beta1 release (Boo!). But it is in our latest 2.0-SNAPSHOT release, and will be in the 2.0.Beta2 release. So if you're daring you can use it now, or you can wait for Beta2 which is right around the corner.

Mike, out.

No comments:

Post a Comment