I'm working on an Apache-licensed persistence plug-in for the qpid C++ broker. Microsoft is funding this work, so naturally it's primary target is Windows. However, Microsoft is also supportive of the notion that the whole community and user base would benefit from a persistence module operating on Linux, Solaris, et al and is therefore supportive of a secondary goal for this work to end up with a portable plug-in that can accommodate multiple database/backing stores under common persistence/recovery code.
At a high level, there are basically three ways to do this... 1. Combine the portable and store-specific code into plug-ins, one per store. Hope that there's only one there when the broker starts. 2. Build the persistence module as one plug-in and the stores are separate "sub plug-ins" that plug into the persistence plug-in. 3. If the persistence plugin is always there, it could be changed from a plugin to a linked-into the broker and the backend stores are the only pluggable pieces. The way #1 works is pretty straight-forward except for the case where there are multiple plug-ins (for example, one for BDB-aio and one for MySQL or Oracle - some sites are very insistent on where their data is stored). The last one initialized wins? #3 may be the simpler way to go, but is more of a departure from today. What do people think of this? #2 is the way I think (at this point) it should work. Much of this would apply to #3 as well. Basically, this would be: - A class MessageStorePlugin is the main plug-in interface point. In addition to inheriting from qpid::Plugin it would also inherit from Plugin::Target - MessageStorePlugin has a "--store=<name>" option to select the backend store. There would have to be a default as well as a way to remember which store was used if the broker is recovering. The <name> part is a name specified by the sub-plugins. Since the names are not all known before option parsing there's no way to validate it during parsing - have to wait until earlyInitialize() - The available store backend plugins are also loaded at broker start along with all the other plugins. As a plugin, they also provide their particular options for parsing. The difference is that when [early]Initialize() is called these don't respond to Broker Targets, they respond to MessageStorePlugin Targets. - During earlyInitialize() the MessageStorePlugin can itself call earlyInitAll, supplying itself as the Target. The store backend plugins recognize the MessageStorePlugin target and call a method on it to supply identifying information like a name (one of which has to match the --store=<name> name) and a pointer/reference. Once this step is done, the MessageStorePlugin can make some association with the selected store backend and be ready for broker restore. That's it for now... Once discussion slows or comes to concensus I'll write something up for the wiki to summarize the resultant approach. Thanks, -Steve --------------------------------------------------------------------- Apache Qpid - AMQP Messaging Implementation Project: http://qpid.apache.org Use/Interact: mailto:[email protected]
