Locating resources in more detail

The skeleton application's use of the socket factory locator did not use its LocatorInfo inner class, although it did make use of the file system locator's one. This is the code from the manager's LifeCyclePlugin:


            wp.add(SkeletonWorkerManager.class, false);

            ...

            FileSystemLocator.LocatorInfo info
                = new FileSystemLocator.LocatorInfo(1024, 1024, true, 1, "disk", 5);
            wp.add("disk", FileSystemLocator.class, info, false);

            wp.add(SocketFactoryLocator.class, false);

Both plugins are added to the worker pool.

Whenever the pool needs to start a new worker it looks up all its IWorkerResourceRequester plugins. Then it creates a new resource handle and passes it to each such plugin for them add their own bindings. At the end of that the worker pool tries to create a new worker netlet with the requirements specified by the resource handle.

Since FileSystemLocator and SocketFactoryLocator both implement the IWorkerResourceRequester interface they are asked about their requirements. In the above example the FileSystemLocator is given a LocatorInfo argument, so, whenever it is called via its IWorkerResourceRequester interface, it uses this to add its requirements to the worker pool's resource handle.

However, when the SocketFactoryLocator plugin is called via its IWorkerResourceRequester interface it finds it wasn't given a LocatorInfo argument as its init argument. So it doesn't do anything.

But the SkeletonWorkerManager, which was also added to the worker pool, also carries the IWorkerResourceRequester interface. So it is also called for its requirements. It responds by looking for a socket factory itself. Here's how:


public class SkeletonWorkerManager extends AbstractPlugin  
    implements IWorkerLifeCycle, IWorkerResourceRequester
{ 
    //...Much work omitted

    public void configureResourceHandle(IResourceHandle resource)
            throws IWorkerResourceRequester.ResourceUnavailableException
    {
        ISocketFactoryLocator sfl
            = (ISocketFactoryLocator)pluginManager().lookup(ISocketFactoryLocator.class)[0];
        IResourceClassHandle[] net_classes = sfl.locateByCount(1, 1);

        if(net_classes.length == 0)
        {
            throw new IWorkerResourceRequester.ResourceUnavailableException(
                "No resource classes");
        }

        try
        {
            resource.addBinding("net", 10, net_classes, null);
        }
        catch (Exception e)
        {
            Debug.exc(this,e,"Resource creation failed");
            throw new IWorkerResourceRequester.ResourceUnavailableException(
                "Resource creation failed");
        }
    }
}

The configureResourceHandle() method is the only method in IWorkerResourceRequester. It simply takes the current resource handle and adds its own bindings to it. The implementation here actually uses the SocketFactoryLocator plugin to do this: it looks it up by its interface then asks it to identify resource classes which can generate one socket with redundancy level 1. If it finds none it fails (though it could try another tactic). If it finds some then it adds a resource binding: binding label net; reuse priority 10 (higher than the priority 5 used for the file system above); any of the resources classes we've just found are suitable; and no warrant for non-local services.

So this code is just what the socket factory locator would do if we had given it an appropriate init argument. But here we have exposed the workings and can see there is opportunity to try other tactics if our first resource grab fails.

Nik Silver 2002-03-09