Look up Singleton Service from other nodes

76 views
Skip to first unread message

Tom Eicher

unread,
Oct 2, 2024, 5:43:25 AM10/2/24
to WildFly
Hello,

on a wf 26.1.3 I have a clustered deployment with a cluster-wide singleton like the standard ha-singleton-service examples.
The service is started fine, one node is "elected as the singleton provider" and started, and does it's thing.

Now, an another node, not the current singleton provider, I need to invoke a method on this service.
I tried
@Inject private MyService service;
@EJB private MyService service;
@EJB(lookup = "java:global/xxxportal/xxxportal-ejb/MyService!com.xxxxx.service.MyService") private MyService service;

but all three just give me the (inactive/unstarted) instance within the same JVM.

How can I invoke a method on the remote active instance?

Thanks Cheers Tom.

Tom Eicher

unread,
Oct 2, 2024, 11:58:55 AM10/2/24
to WildFly
Okay, trying and googling this all day,
I think I need to "bridge" this MSC service into the EE world,
e.g. by providing a @Stateless bean that looks up the MSC service, and calls the method.
Is this correct?

However, I seem to be unable to lookup the MSC service.

1. via InitialContext?
I tried several combinations, but always get NameNotFound
when the deployment logs sais
16:20:43,707 INFO  [com.xxxxx.core.init.SingletonServiceActivator] (MSC service thread 1-8) Singleton service activated.
...
16:20:55,833 INFO  [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0003: node1 elected as the singleton provider of the com.xxxxx.core.init.singleton.service service
what would be the string to give to new InitialContext().lookup()?

2. via 
but CurrentServiceContainer.getServiceContainer() is always null inside a @Stateless in my ear module.

Cheers Tom.

Paul Ferraro

unread,
Oct 9, 2024, 5:09:03 AM10/9/24
to WildFly
Singleton services were never intended to be directly invokable.  If possible, I would suggest packaging your logic into a @Singleton EJB, and deploying it as a singleton service.
You can then make traditional remote EJB invocations to the singleton EJB, which should only ever be deployed on one server of your cluster.

Alternatively, if you don't mind using WildFly specific APIs, you can leverage WildFly's CommandDispatcher to dispatch commands to the primary provider of your singleton service as a means to invoke on your singleton.

N.B. The singleton service installation API saw some much needed improvements for WF34, so the code below is specific to WF34 and later:

@MetaInfServices(ServiceActivator.class)
public void MySingletonServiceActivator implements SingletonServiceActivator {
    @Override
    public void activate(SingletonServiceActivatorContext context) {
        SingletonServiceTarget target = context.getServiceTarget();
        SingletonServiceController<?> singleton = target.addService().setInstance(new MyService()).install();
        // Bind Singleton to JNDI for use by EE components
        new InitialContext().bind(..., singleton);
    }
}

From your application code, you can observe the state of the singleton and dispatch commands to the primary provider:
e.g.

@jakarta.ejb.Singleton
public void MySingletonBean {
    @Resource(lookup = "jboss:clustering/server/command-dispatcher-factory/server")
    CommandDispatcherFactory<GroupMember> dispatcherFactory;
    CommandDispatcher<GroupMember, MySingletonBean> dispatcher;

    @PostConstruct
    public void init() {
        this.dispatcher = dispatcherFactory.createCommandDispatcher("foo", this);
    }

    @PreDestroy
    public void destroy() {
        this.dispatcher.close();
    }

    public void invokeOnPrimary() {
        Singleton singleton = (Singleton) new InitialContext().lookup(...);
        Optional<GroupMember> member = singleton.getSingletonState().getPrimaryProvider();
        if (member.isPresent()) {
            Command<Foo, MySingletonBean, RuntimeException> command = new FooCommand<>();
            CompletionStage<Foo> result = this.dispatcher.dispatchToMember(new FooCommand<>(), member.get());
            // ...
        }
    }
}

Paul
Reply all
Reply to author
Forward
0 new messages