Wednesday, February 18, 2009

OSGi Service Hooks

I made sure not to have any conferences or meetings in February so I could focus on the writing of the specifications. It is now half way through the month and it has been a crazy month, even worse than usual. Though I have not been able to devote nearly 25% of the time to the specifications as I intended, it looks like the Service Hooks specifications are basically finished.

So what are these Service Hooks? Service hooks complement the OSGi service programming model. The current model is based on the following primitives:
  • Register a service (Publish)
  • Find services (Find)
  • Get a service (Bind)
  • Listen for service events
The service registry acts as a mediator between the publishing and finding/binding party. Due to RFC 119 Distributed OSGi, we discovered that we were missing primitives in the service registry. One of the key requirements in RFC 119 was to be able to provide services on demand. However, you can only provide services on demand when you know what bundles are waiting for. The beauty of the OSGi service registry is that this information is available through the internal registry of Service Listeners. Service Listeners are registered with a filter that contains the information about their interest. The Listener Hook provides this information. Registering a Listener Hook service will provide the caller with an initial list of all registered Service Listeners and is then kept informed of additions and removals.

During the write up of the specification for the Listener Hook a huge discussion erupted about ordering. Should the events of the adding/removing Service Listeners be ordered or not? There are two sides to this debate. Ordering is much easier for the hook implementer but it turns out that this is quite difficult for the Framework because these events are originating deep down in the bowls of the service registry. The occurrence of the out of order delivery is also very rare, though the chance is finite. After long discussions we found the solution in an extra method on the event object that indicated the state of the event object. This allows the hook implementer to easily find out that a specific delivery is out of order inside a synchronized block and ignore the event. The most scary part was that we also discovered that the same out of order case was possible with service events. Something none of us had ever realized.

The second use case for the hooks was proxying. With proxying, you want to hide the original service and provide an alternative. However, in current OSGi you cannot hide a service for another bundle. Meet the Event and Find Hooks! The Event Hook is a service that receives a service event before it is delivered to the bundles. As a bonus, it can remove bundles from the delivery list, effectively hiding events from that bundle. Its counterpart is the Find Hook that gets a chance to look at, and reduce, the results of the getServiceReference and getServiceReferences methods. This hook can remove Service Reference objects from the result, also effectively hiding the service from the caller.

One of the issues we found was that these hooks need to be implemented very carefully because, depending on when they begin, they can partially hide events from a bundle, creating the wrong image for that bundle. For example, if a bundle already has a service before you hide future events, it is easy to hide the unregister event for that bundle. Fortunately, we found out that the service tracker could handle most of these partial events, but if you hide an unregister event for a service, the service tracker could hold on to that service forever.

Clearly, these hook services are not for the faint of heart. They are very close to the framework and require to be very well-behaved. That said, they definitely look like they will enable new software patterns for more symmetric service programming. It is likely that utilities like the Service Tracker, or extensions to the OSGi programming models, are created on top of these hooks.

Peter Kriens

Thursday, February 12, 2009

OSGi and Second Hand Cars

An interesting aspect of the Internet is that you get so many examples of where software goes terribly wrong. Today I received a very nice mail from Sophy that warmed my heart.

Hi,
My name is Sophy Jhonston. I've just visited your website ( osgi.org ) and I was wondering if you'd be interested in exchanging links with my website?. I can offer you a link back from my Cars Guide website which is (http://www.wooricar.net)with page rank 3. Your link will be placed here: http://www.wooricar.net/Car-History.html (It`s a Cars Guide website with page rank 3)
...
I hope you have a nice day and thank you for your time,

Sophy Jhonston


Sophy, thanks for this wonderful example of the (sad) state of the software art. As thanks, hereby your link and please add us at your highly ranked car page. I might do wonders for our Vehicle Expert Group!

Peter Kriens

Monday, February 2, 2009

Ordering? Get Over It!

One of the ever recurring discussion in OSGi is about ordering during initialization. Ordering is the siren song that we are often so lured by as a shortcut to handle the actual dependencies. Ordering can work if you're the omnipotent god in your project and you can oversee all the details. However, for mere mortals it creates very brittle software that is highly unlikely to work in other environments. Just the fact that in OSGi any bundle can be stopped wreaks havoc with any ordering model. However, many are strengthened in their pursuit of simpleness when they discover the start level service! The start level service seems to offer ordering! Yes, it is clearly one of the pretty sirens!

However, the start level service is a tool of the deployer. Writing your code with the assumption that the deployer will setup all the bundles properly and handle all edge cases will only work when you're the deployer and you will never get sick. And even then, you'll likely spent a lot of time chasing dependency issues that could easily have been prevented.

And the only thing you really need is the mindset that dependencies should be explicit and managed. In OSGi, dependencies are handled through services and packages. Package dependencies make sure that you can build code on solid ground by ensuring that all your required code dependencies are managed. That is, you won't run if the classes are not available. So when your code runs, it has a well defined environment. However, this model is not suitable for the myriad of dependencies that we should handle in modern software. Log service is up? Do I get configuration? Is my communication provider up? Is there a properly initialized database? You know what I am talking about.

In non-OSGi software may of these dependencies are handled implicity with a lazy initialization model. This is one of the key reason that Spring became so succesful: it provide a model where you could specify all this ordering and configuration in just one place. Though this works amazingly well for monolithic applications, it does not scale so well with lots of independently developed components because all the ordering and configuration details must be handled centrally. Creating the so called "godess" spring file. In a large systen, there is a huge advantage to allow independent components to form the application. Independent components can be developed easier, can be made more robust, and allow the final application more flexibility in deployment. However, this requires that each component specifically states its dependencies.

It turns out that virtually any dependency can be mapped to the OSGi service model. It is a bit of a paradox, but because OSGi services are so unreliable, you can make extremely robust systems because real world dependencies are all too often dynamic. If you use OSGi services for all your dependencies, there is no need to use start level ordering to make the initialization work.

So what is the purpose of the start level service? Well, there are many cases where you can improve the performance or appearance of a system by ordering the initialization. For example, if one of your bundles is a flash image to show the system, then it has it advantages that this image is visible during the first second when your system starts. There is also the issue that some orderings are more smooth than others. Starting some strategic bundles first can make a significant improvement. However, this is the toy of the deployer and bundles that make assumptions about other bundles without explicitly handling them are just bad bundles ... however attractive startlevel number 2 might appear.

Peter Kriens

EclipseCon and OSGi DevCon Early Registration

Don't forget to