Ready to serve requests ...

In the Apache Sling project we have an interesting problem: Knowing when the application has finished its startup.

Coming from a background of a traditional application, you know when the system has finished its startup. For example, a servlet container knows it has finished the startup, when all web applications have been started.

In Apache Sling, the situation is a bit different: Apache Sling is an extensible system, where extensions may simply be added by adding more bundles. "Easy", you say, "just wait for all bundles to have been started and you know when the application is ready". True, but there is a catch.

To extend Apache Sling, you register services with the OSGi registry. "Still easy", you might say. Right, if the services are all started by bundle activators, we still can depend on having all bundles started for the system to be ready.

Again, this is only part of the story: Some services depend on other services. So the dependent services may only be started when the dependencies get resolved. This is where the trouble starts.

To help solve the dependency issues in a simple way, we employ OSGi Declarative Services. Great things to define components and services and have the dependency requirements being enforced and have dependency injection and configuration support and ... much more.

"What does it cost?", you say. Well, we buy this functionality with a lot of asynchronicity: When all bundles have been started, not all components may have been activated and not all services may have been registered.

Now, when is the application ready ? I cannot easily tell.

One approach could be to have a special service to watch out for a configurable list of services to be available. When all services are available and after the framework has started, the service signals Application Ready. As soon as one of the services goes away, the service might signal Application Not Ready.

The real question raising now is: What services are required for the application to be considered ready ? Can we come up with such a list ? How to we manage this list in light of more services to come, which might be considered vital ?

Any input would be appreciated ;-)

Kommentare

Todor Boev hat gesagt…
I think in OSGi we should avoid the good old "setup -> activate" thinking. In the dynamic environment things are always partially setup. Basically every bundle should start doing it's job as soon as activated and have good exception handling coded for unexpected crashes. The bundles will try and crash several times until everyone fall in their place and the useful activities start to "come through". For state initialization this means - do it lazily. For threads it means - start in the activator and don't bother more. For any event driven I/O sources: just hook up to them in the activator. I.e. act as if all external objects are always available and can also always crash. Than this can be performance tuned: wait for a timeout before crashing or ultimately block until a predefined set of resources are available. This latter option has shown to be really hard to get right - so hard I think the performance hit of some active polling is well worth the simplicity. Also too often we do want to handle the crash anyway: return an error page, display a dialog to the user and so on.
fmeschbe hat gesagt…
From the OSGi point of view I could not agree more... But users of our web application system are nervous and want to know when the system is ready.
Also we want to be somewhat informative if something does not work due to a bundle or service not being available for any one reason.

Beliebte Posts aus diesem Blog

OSGi Bundles require Classes from the Environment

LinkedHashMap's hidden (?) features

To embed or to inline ?