Managing plugins remotely

A rather ingenious feature of Beatrix's plugins is remote plugin management.

The plugin interface IRemotePluginManager, and its implementation RemotePluginManager, both live in package org.jtrix.project.beatrix.plugins. The Worker netlet provides this via an internal facet. It allows a remote netlet to add, remove and lookup plugins as usual.

The plugin interface IRemoteServiceManager, and its implementation RemoteServiceManager, do the same for service plugins. However, they are in org.jtrix.project.beatrix.plugins.util and are not part of the Worker by default.

Here is an example of both in action. The skeleton's manager responds to a worker-started event by adding plugins, turning the Worker from a do-little netlet into a worker netlet designed for this application. Among the plugins it adds and uses a RemoteServiceManager. All this takes place in the skeleton manager's own IWorkerLifeCycle plugin because it's the workerStarted method that will be called when any new worker starts:


public class SkeletonWorkerManager extends AbstractPlugin  
    implements IWorkerLifeCycle, IWorkerResourceRequester
{ 
    public void workerStarted(IWorkerHandle worker)
    {
        try
        {
            IInternalFacetCache ifc
                = (IInternalFacetCache) pluginManager()
                    .lookup(IInternalFacetCache.class)[0];

            // Find remote plugin manager and add two plugins

            IRemotePluginManager pm
                = (IRemotePluginManager)ifc.getInternalFacet(
                    worker, IRemotePluginManager.class.getName(), null, true);
            pm.remoteAdd(RemoteServiceManager.class, false);
            pm.remoteAdd(SkeletonWorker.class, true);

            // Remotely add a service provider plugin

            IRemoteServiceManager sm
                = (IRemoteServiceManager)pm.remoteLookup(IRemoteServiceManager.class)[0];
            sm.remoteAdd("skeleton",SkeletonServiceProvider.class, null, false);
        }
        catch(BeatrixPluginException e)
        {
            // Adding a plugin failed
        }
        catch(BeatrixFacetException e)
        {
            // Getting an internal facet failed
        }
    }

    // ...Much work omitted
}

Notice that the SkeletonWorker plugin is told to ``eager initialise''--i.e. initialise immediately. This ensures its init() method is called which in this case binds its resources, but in general could do anything to bootstrap that netlet.

Nik Silver 2002-03-09