Article: The Whiteboard Pattern for OSGi

Discussions

News: Article: The Whiteboard Pattern for OSGi

  1. "The Whiteboard Pattern for OSGi" is the second in TSS' series on OSGi, this time focusing on a common pattern in OSGi, called the "whiteboard pattern," where interfaces that can fulfill a contract are searched for in an OSGi repository. It's important to understand OSGi before reading this one - but this one's where you start to learn how to use OSGi fo shizzle.
    In the first article, we built a truly primitive infobot. It responded to "~put factoid_name factoid" and "~get factoid_name," where the factoid names were basically XPath expressions. (What's more, with the XUL repository, they're truly XPath expressions: you could put in "~get /fact/*" and get the first of any number of nodes, depending on how the XPath engine reported nodes back.) However, fixing the infobot in any way meant uninstalling it and re-installing it, and presumably restarting the darned thing. That's no fun. We should be able to have a deployable bot where new commands can be installed at any point. This is perfect for the whiteboard pattern. We can install a pircbot implementation, and have the onMessage() method look for implementations of IRCCommand, passing the message to each command in turn (possibly stopping when the command is consumed.) If a command is broken, we can uninstall the command, fix it, and reinstall - all transparent to the IRC bot. Even our factoids can be implemented this way, so our IRC Bot turns into a whiteboard consumer, and can do anything we can think of to make it do.
  2. The article states that: "Basically, the whiteboard pattern is this: a content provider registers itself into the OSGi service registry. A content consumer regularly polls the registry for consumers of the content provider type, and then calls each one in turn." Shouldn't this be: Basically, the whiteboard pattern is this: a content provider registers itself into the OSGi service registry. A content consumer regularly polls the registry for PROVIDERS of the content provider type, and then calls each one in turn. change consumers -> PROVIDERS Thanks.
  3. I/F IRCCommand[ Go to top ]

    public interface IRCCommand { IRCMessage handleCommand(Ebot bot, IRCMessage message); } The signature of the handleCommand has two parameters , yet in the code that follows, method onMessage and the class Command it is called with only one parameter, the IRCMessage. Am I missing something? Cheers.
  4. Re: I/F IRCCommand[ Go to top ]

    Yes, it's the joy of writing an article and code and not re-syncing the two after I was done with part of it. In other words: "whoops." :)
  5. Events[ Go to top ]

    Why poll in a thread ? Why not use events, so when the new service with corresponding set of parameters is registered, we can consume something from it.
  6. Re: Events[ Go to top ]

    Why poll in a thread ? Why not use events, so when the new service with corresponding set of parameters is registered, we can consume something from it.
    It depends on the need! For one thing, neither article (the first or second) uses OSGi lifecycle for anything other than starting or stopping. Looking for registration events is a separate issue. I can *certainly* go into that if you'd like - *I* just haven't needed it yet, so I don't have a use case with which I can illustrate a valid, sensible usage.
  7. dumb question: Where can I get a jar containing ServiceTracker?
  8. dumb question: Where can I get a jar containing ServiceTracker?
    Depends on the OSGi container you use. For Equinox, it's in org.eclipse.osgi_3.3.2.R33x_v20080105.jar - or similar, depending on the specific Equinox release you have.
  9. dumb question: Where can I get a jar containing ServiceTracker?
    Depends on the OSGi container you use. For Equinox, it's in org.eclipse.osgi_3.3.2.R33x_v20080105.jar - or similar, depending on the specific Equinox release you have.
    So there's no standard jar for this? That seems weird.
  10. dumb question: Where can I get a jar containing ServiceTracker?
    Depends on the OSGi container you use. For Equinox, it's in org.eclipse.osgi_3.3.2.R33x_v20080105.jar - or similar, depending on the specific Equinox release you have.


    So there's no standard jar for this? That seems weird.
    ServiceTracker is part of OSGi Compendium jar and is defined in the compendium specs. As is quite central to osgi development most framework implementations include it in the system bundle so practically you can rely on importing it without installing any other additional bundle (jar). Alin Dreghiciu
  11. I have a couple of concerns/questions about this approach. First, the code for stopping the thread (which you got from the whitepaper) doesn't seem proper to me. The run method is synchronized (for reasons that are unclear to me) but the stop method is not. As I understand it, there's no guarantee that the cache containing 'thread' for the thread that calls stop will be pushed to the cache for the thread that's calling the run() method. I don't think synchronizing on one side is enough. Unless I am mistaken, that just works by accident. Secondly, I played around with this and moved the wait between the getServices() call and the loop over the services. If I stop or even uninstall the clock bundle between getServices and the getContent() call, it still works. That's a little confusing to me. Shouldn't uninstalling the bundle invalidate references to the services supplied by that bundle?
  12. OSGi Service Platform Core Specification Release 4, Version 4.1, Section 4.3.9
    The BundleActivator interface defines a stop(BundleContext) method, which is invoked by the Framework to stop a bundle. This method must release any resources allocated since activation. All threads associated with the stopping bundle should be stopped immediately. The threaded code may no longer use Framework-related objects (such as services and BundleContext objects) once the stop method returns. If the stopping bundle had registered any services during its lifetime, then the Framework must automatically unregister all registered services when the bundle is stopped. It is therefore unnecessary to unregister any services in the stop method.
    The Framework must guarantee that if a BundleActivator.start method has executed successfully, that same BundleActivator object must be called with its BundleActivator.stop method when the bundle is deactivated. After calling the stop method, that particular BundleActivator object must never be used again.
    Packages exported by a stopped bundle continue to be available to other bundles. This continued export implies that other bundles can execute code from a stopped bundle, and the designer of a bundle should assure that this is not harmful. Exporting interfaces only is one way to prevent such unwanted execution when the bundle is not started. Generally, to ensure they cannot be executed, interfaces should not contain executable code.
    So as I read this, an exported package must remain available even when the bundle is stopped (also uninstalled) but services are to go away immediately. If we take the clock example and made it have a thread which is used internally to satisfy requests, it would (according to the spec) need to be stopped 'immediately' when the bundle is stopped. That would mean that it could no longer service requests. Assuming I understand this properly, doesn't this mean that the whiteboard pattern suffers from a race condition? There's a (non-atomic) gap between when the services are retrieved and when they are called. In the example above the gap is too small for this to create an issue but what if the lookup returned dozens or hundreds of services? The last one might not be called for several seconds or even minutes depending on the time it takes to call each of the preceeding services. I'm not bringing this up to be a pain in the ass. I really want to understand OSGi and if I'm wrong on this, I'd like to understand why.
  13. I don't know how to take the lack of response on this. Am I so wrong that no one can bring themselves to point it out or something?
  14. I don't know how to take the lack of response on this. Am I so wrong that no one can bring themselves to point it out or something?
    *I* just don't have a good answer for you. OSGi is *supposed* to have fewer problems with synchronization, but I haven't run into the problem you talk about - that doesn't mean it doesn't exist, it just means I have no answer for you. I'm tempted to say "YAGNI" but I have no real reason to say that. I don't know.
  15. The article says,
    Basically, the whiteboard pattern is this: a content provider registers itself into the OSGi service registry. A content consumer regularly polls the registry for consumers of the content provider type, and then calls each one in turn. That's fairly simple, but let's show some code to make it obvious, through two examples: one to illustrate the pattern itself, and another to build on our IRC bot example from the first tutorial, by adding a command system where new commands can be installed as OSGi bundles at runtime.
    but the Whiteboard white paper defines it as,
    Instead of having event listeners track event sources and then register themselves with the event source, the whiteboard pattern has event listeners register themselves as a service with the OSGi framework. When the event source has an event object to deliver, the event source calls all event listeners in the service registry. Remarkably, the event source is not registered with the framework as a service....
    Oddly, the code in both the white paper and the article match the article's version.
  16. Hi, Unless I have missed something? This looks likes the Observer pattern e.g. java.util.Timer. So I could start a timmer that runs every 15 secs and calls all TimerTask to display things every 15 secs. What is supposed to be new? Ben.