Monday, March 19, 2012

Shared Transport in JGroups

A transport in a JGroups application is a heavy-weight concept and a majority of the JGroups entities (remote procedure call, replicated hash map, etc.) generally require their dedicated channels for communication. However, by sharing a transport between multiple channels, it is possible to optimize available resources. (Remember that each transport occupies a thread pool and a socket.) For this purpose, one just needs to set the singleton_name attribute for the transport.


Unfortunately, it is not possible to alter the singleton_name attribute of a transport using something like:
String singletonName = "yabba";
JChannel channel = new JChannel();
channel.getProtocolStack().getTransport()
        .setValue("singleton_name", singletonName)
At the moment, for this purpose, you have to alter the XML specification of the channel you are using. (See Bela Ban's reply to Setting Up a Shared Transport post in JGroups mailing-list.)
For this purpose, I put together a ChannelFactory as follows.
final class ChannelFactory {
    private static ChannelFactory instance = null;
    private static final String singletonName = "shared";
    private List channels;

    private ChannelFactory() {
        channels = new ArrayList();
    }

    synchronized JChannel create() throws Exception {
        JChannel channel = new JChannel(
                this.getClass().getClassLoader()
                        .getResource("META-INF/channel.xml"));
        channels.add(channel);
        return channel;
    }

    synchronized void clear() {
        for (JChannel channel : channels) {
            channel.disconnect();
            channel.close();
        }
        channels.clear();
    }

    static synchronized ChannelFactory getInstance() {
        if (instance == null)
            instance = new ChannelFactory();
        return instance;
    }
}
Later, I copied (say) udp.xml from JGroups sources to META-INF/channel.xml. And I added singleton_name="shared" line to the protocol specification in META-INF/channel.xml file.

Now, my individual classes make calls to ChannelFactory.getInstance().create() to get a channel dedicated to them. And while program shuts down, I just make a call to ChannelFactory.getInstance().clear() to tidy things up.

No comments:

Post a Comment