A common solution for a recurring problem can be named as a pattern. Patterns are everywhere. More often than not, we adopt patterns for computer science from our day to day life experiences. White board pattern is one such common pattern. The pattern allows you to decouple two parties from each other (consumer/provider). I came across this pattern for the first time during my final year project. We worked on a distributed Tuple space implementation and end user-apps used white-board pattern to publish/consume data-strings to/from the tuple space.
The pattern is analogous to a notice board. When ever one wants to publish something to the world/audience, he/she goes and stick the note on the notice board. The interested party can pick up the note. This makes provider and consumer decoupled from each other.
White-board in OSGi ?
In OSGi programming model we do have notice board like mechanism. The OSGi service registry provided by the runtime can act as the whiteboard for publishers/consumers. In OSGi jargon we called them services. We can publish and lookup services that resides in OSGi service registry.
Why not Observer pattern to consume services ?
One common way to consume OSGi services is to use Observer pattern. Here we acquire the service using an API look-up from the service registry and register our implementation against the exposed service.
Think about a web-app that runs inside an OSGi environment. One of the bundle publishes the standard http.service (http service is the link between servlet transports and the OSGi environment) to the environment and service consuming bundles should hookup their servlets to the published http.service.
Here bundle foo has a servlet implementations that has to be registered under context /foo and likewise bundle bar wants to register a servelet under context /bar. Http.Service allows you to register a servlet using the API method,
registerServlet(String context, Servlet servlet); // example method signature.
Hooking in to the Http.Service using Observer pattern
When using observer pattern, the foo and bar bundles become observers. The individually lookup for http.service from the OSGi service registry and registers their respective servlets against preferred contexts using http.service API.
As depicted above, each bundle has to acquire the http.service through service lookup and register their servlets against http.service.
The same using white board pattern
In this scenario, instead bundles looking up for http.service, they themselves publish their servlet implementation with OSGi service registry. Then who does the http.service and servlet hooking up part ?. There we have another bundle to take care of that. It looks up both http.service implementations and servlet implementations from the OSGi service registry and hook them up together.
- The consumers are no longer depend on the service providers interface. Instead they just have to adhere to servlet.api interface.
- The change in the http.service API will affect only the service binding bundle implementation. It will not affect the consumers.
- The life-cycle of the consumer bundle does not get affected by the http.service. That is, it can survive in a OSGi runtime where http.service is not available.
We use the above pattern during servlet registration process in the WSO2 Carbon servers. Recently while doing some code hacking, I saw the same pattern in pax-logging code. They use it to hookup hookup layouts, appenders and filters to the logging engine.