Wednesday, October 20, 2010

Programmatic creation of a channel

I've committed code which provides programmatic creation of channels. This is a way of creating a channel without XML config files. So instead of writing

JChannel ch=new JChannel("udp.xml");

, I can construct the channel programmatically:


JChannel ch=new JChannel(false);                 // 1
ProtocolStack stack=new ProtocolStack(); // 2
ch.setProtocolStack(stack);              // 3
stack.addProtocol(new UDP().setValue("ip_ttl", 8));
     .addProtocol(new PING())
     .addProtocol(new MERGE2())
     .addProtocol(new FD_SOCK())
     .addProtocol(new FD_ALL().setValue("timeout", 12000));
     .addProtocol(new VERIFY_SUSPECT())
     .addProtocol(new BARRIER())
     .addProtocol(new NAKACK())
     .addProtocol(new UNICAST2())
     .addProtocol(new STABLE())
     .addProtocol(new GMS())
     .addProtocol(new UFC())
     .addProtocol(new MFC())
     .addProtocol(new FRAG2());       // 4
stack.init();                         // 5


First, a JChannel is created (1). The 'false' argument means that the channel must not create its own protocol stack, because we create it (2) and stick it into the channel (3).

Next, all protocols are created and added to the stack (4). This needs to happen in the order in which we want the protocols to be, so the first protocol added is the transport protocol (UDP in the example).

Note that we can use Protocol.setValue(String attr_name, Object attr_value) to configure each protocol instance. We can also use regular setters if available.

Finally, we call init() (5), which connects the protocol list correctly and calls init() on every instance. This also handles shared transports correctly. For an example of how to create a shared transport with 2 channels on top see ProgrammaticApiTest.

I see mainly 3 use cases where programmatic creation of a channel is preferred over declarative creation:
  1. Someone hates XML (I'm not one of them) :-)
  2. Unit tests
  3. Projects consuming JGroups might have their own configuration mechanism (e.g. GUI, properties file, different XML configuration  etc) and don't want to use the XML cofiguration mechanism shipped with JGroups.
Let me know what you think about this API ! I deliberately kept it simple and stupid, and maybe there are things people like to see changed. I'm open to suggestions !


Cheers,

9 comments:

  1. I'd rather like to do like the following:

    JChannelBuilder builder = new JChannelBuilder();
    builder.addProtocol(...);
    ...
    JChannel ch = builder.newChannel();

    .. instead of adding more public methods to JChannel.

    ReplyDelete
  2. Why ? There are *no* new public methods in JChannel.

    ReplyDelete
  3. Could you stick this in an annotation?
    I could then make the program decide how to open a channel based om some logic. fi. if the debug flag is true.

    ReplyDelete
  4. Stick what into an annotation ?

    ReplyDelete
  5. Ohh, this is great feature...
    It is exactly what I need.

    Um working mostly on WebSphere platform.
    WebSphere clustering is term of own configuration.

    This might be a solution for JGroups to be configured automatically in proprietary App Server.
    Only configuration option to be supplyed per instance is UDP port to be bind as java -D argument.
    Implementation itself could be an OSGi service, pluggable into WebSphere's eclipse runtime.

    In cloud aware environment, there is always a kind of supervisor, which could control distributed cache directory initialization and control.

    The features I would see:
    OSGi extension point?
    Range of neighbors could be limited by providing known pairs, supervisor should be aware of.
    This can cat multicast traffic?

    Many other approaches...

    ReplyDelete
  6. Before we have the new API, we can use the new JChannel(String) constructor.

    String protocolStack = XmlConfigurator.getInstance(this.getClass().getResourceAsStream("/jgroups.xml")).getProtocolStackString();//just copy and save this string, set as a constant or whatever
    Channel channel = new JChannel(protocolStack);

    It meets all the 3 use cases.

    ReplyDelete
  7. Uh, I thought JChannel(boolean) and setProtocolStack() were added.

    ReplyDelete
  8. No, they were there before

    ReplyDelete
  9. Nice post! Thanks and keep on sharing.
    Michael

    ReplyDelete