4 Replies Latest reply on Nov 2, 2016 3:34 PM by pferraro

    Creating a custom JGroups channel for a cluster

    mylos78

      Hi all !

      I would like to know if it's possible to define a new WildFly cluster channel (besides "ejb" and "web") somehow, so that for example I can use it just for my web application. Any way to do it with management interfaces or programmatically ?

      Thanks

      Mylos

        • 1. Re: Creating a custom JGroups channel for a cluster
          pferraro

          In WildFly 8, the JGroups subsystem defines protocol stacks, from which channels can be built.  Each protocol stack exposes a ChannelFactory, from which new channel can easily be created programmatically.

           

          In WF8, you can create/connect a channel named "foo", with a cluster name "cluster" that uses the "udp" stack using a service activator:

          public class ChannelServiceActivator implements org.jboss.msc.service.ServiceActivator {
              @Override
              public void activate(ServiceActivatorContext context) {
                  ServiceName name = ServiceName.of(...);
                  InjectedValue<ChannelFactory> factory = new InjectedValue<>();
                  context.getServiceTarget().addService(name, new MyService(factory))
                          .addDependency(ChannelFactoryService.getServiceName("udp"), ChannelFactory.class, factory)
                          .install();
              }
          }
          
          public class MyService implements org.jboss.msc.service.Service<Channel> {
              private final Value<ChannelFactory> factory;
              private volatile Channel channel;
          
              public MyService(Value<ChannelFactory> factory) {
                  this.factory = factory;
              }
          
              @Override
              public Channel getValue() {
                  this.channel = channel;
              }
          
              @Override
              public void start(StartContext context) {
                  this.channel = this.factory.getValue().createChannel("foo");
                  this.channel.connect("cluster");
              }
          
              @Override
              public void stop(StopContext context) {
                  this.channel.disconnect();
                  this.channel.close();
                  this.channel = null;
              }
          }
          
          
          
          
          

           

          WildFly 9 will add the ability to declaratively define channels as well as fork channels (see http://www.jgroups.org/manual/index.html#ForkChannel) and inject them into your application via JNDI.  Fork channels are particularly useful for allowing multiple services (including Infinispan caches) to share a channel instance.

           

          To create a JGroups channel in WF9 (master), the service activator instrumentation used in the WF8 example is completely unnecessary.  You can either define a new channel directly in the subsystem and inject it into your application, or inject the ChannelFactory and create/connect the channel programmatically.

          e.g.

          <subsystem xmlns="urn:jboss:domain:jgroups:3.0">
              <channels default="ee">
                  <channel name="ee"/>
                  <channel name="foo"/>
              </channels>
              <stacks default="udp">
                  <stack name="udp">
                      <!-- ... -->
                  </stack>
             </stacks>
          </subsystem>
          
          
          
          
          

          As always, anything declarable via the domain configuration xml is definable via the management API.

           

          You can either inject the "foo" channel directly:

          @Resource(lookup = "java:jboss/jgroups/channel/foo")
          private Channel channel;
          
          @PostConstruct
          public void init() {
              this.channel.connect("cluster");
          }
          
          @PreDestroy
          public void destroy() {
              this.channel.disconnect();
          }
          
          
          
          
          

           

          ... or inject the channel factory and create the channel manually, e.g.

          @Resource(lookup = "java:jboss/jgroups/factory/default") // "default" refers to the default stack
          private ChannelFactory factory;
          private Channel channel;
          
          @PostConstruct
          public void init() {
              this.channel = this.factory.createChannel("foo");
              this.channel.connect("cluster");
          }
          
          @PreDestroy
          public void destroy() {
              this.channel.disconnect();
              this.channel.close();
          }
          
          
          
          
          

           

          In subsequent WF9 releases, you'll be able to define and create fork channels in a similar way, where a ChannelFactory is exposed both per <stack/> (to create a JChannel) and per <channel/> (to create a ForkChannel).  That work is here, and is awaiting merge:

          WFLY-4105 Add support for explicit fork channel protocols by pferraro · Pull Request #6992 · wildfly/wildfly · GitHub

          • 2. Re: Creating a custom JGroups channel for a cluster
            mylos78

            Thank you very much for the valuable and authoritative reply Paul!

            • 3. Re: Creating a custom JGroups channel for a cluster
              java.food

              I tried using this approach with WF 9 and 10 (in both standalone and domain configuration), but I am not having any success.  First of all, there is no java:jboss/jgroups/channel/<channel name> or java:jboss/jgroups/factory/default in JNDI.  However, there is a java:jboss/jgroups/factory/udp.  However, java:jboss/jgroups/factory/udp is of JChannelFactory type, not ChannelFactory type.  Are there other configuration changes need to be done in order for this approach to work?

              • 4. Re: Creating a custom JGroups channel for a cluster
                pferraro

                java.food Can you post the code you are trying to use?