3

if we look inside DefaultThreadFactory of Jgroups the following code is present

protected Thread newThread(Runnable r,String name,String addr,String cluster_name) { String thread_name=getNewThreadName(name, addr, cluster_name); Thread retval=new Thread(r, thread_name); retval.setDaemon(createDaemons); return retval; }

As new thread is used so I believe in a managed server environment this can cause issues and is also not a good practice.

If I just replace the default thread factories and executors with Managed factories and executors of WebSphere will the behavior of Jgroups be still the same ?

Any pointers will be helpful ..?

Update

My intention is to use JGroups with WebSphere AS 8.5. I am keen to not have any un-managed threads. My main use case is for leader election and some message passing. It will be used to manage Spring Integration pollers and ensure only one poller is running within the cluster.

WAS 8.5 still uses the CommonJ api for Work management.

I am using Spring to abstract the Task Executors and Schedulers.

It was initially easy enough to replace the ThreadPools with task executors as they share the Executor api.

The TaskScheduler had to be adapted to work with your TimeScheduler interface. They are very similar and perhaps extending from the ScheduledExecutorService could be an option here. I implemented to your interface and delegated to Springs TaskScheduler.

The main issue is with the ThreadFactory. CommonJ does not have this concept. For this I created a ThreadWrapper that encapsulates the Runnable and delegates out to a TaskExecutor when the "Thread's" start method is called. I ignored the thread renaming functionality as this will not have any effect.

public Thread newThread(Runnable command) {
    log.debug("newThread");
    RunnableWrapper wrappedCommand = new RunnableWrapper(command);
    return new ThreadWrapper(taskExecutor, wrappedCommand);
}

public synchronized void start() {
    try { 
        taskExecutor.execute(runnableWrapper);          
    } catch (Exception e) {
        throw new UnableToStartException(e);
    }
}

This is where I ran into problems. The issues were in the transports. In a number of cases with in the run method of some of the internal runnables e.g. the DiagnosticsHandler, the TransferQueueBundler of TP and ViewHandler of GMS there is a while statements that checks the thread.

public class DiagnosticsHandler implements Runnable {
    public void run() {
        byte[] buf;
        DatagramPacket packet;
        while(Thread.currentThread().equals(thread)) {
            //...
        }
    }
}

protected class TransferQueueBundler extends BaseBundler implements Runnable {
    public void run() {
        while(Thread.currentThread() == bundler_thread) {
            //...
        }
    }
}

class ViewHandler implements Runnable {
    public void run() {
        long start_time, wait_time;  // ns
        long timeout=TimeUnit.NANOSECONDS.convert(max_bundling_time, TimeUnit.MILLISECONDS);
        List<Request> requests=new LinkedList<>();
        while(Thread.currentThread().equals(thread) && !suspended) {
            //...
        }
    }
}

This does not co-operate with our thread wrapping. If this could be altered so that the equals method is called on the stored thread it would be possible to override it.

As you can see from the various snippets there are various implementations and levels of protections varying from package, protected and public. This is increased the difficulty of extending the classes.

With all of this done it still did not remove completely the issue of unmanaged threads.

I was using the properties file method of creating the protocol stack. This initialises the protocol stack once the properties are set. To remove the Timer threads that are created by the bottom protocol. The TimeScheduler must be set prior the to stack being initialised.

Once this is done the threads are all managed.

Do you have any suggestions on how this could have been achieved more easily?

user666
  • 1,104
  • 12
  • 20

1 Answers1

0

Yes, you can inject your on thread pools, see [1] for details.

[1] http://www.jgroups.org/manual/index.html#_replacing_the_default_and_oob_thread_pools

Bela Ban
  • 2,186
  • 13
  • 12
  • Thanks for replying I have been through this blog post..I will be very happy if you can tell me that replacing these with JSR 236 Concurrency Utilities will provide the desired effect. I am a bit confused about other variables used in thread factories for eg BaseName etc – user666 Nov 26 '15 at 14:54
  • 1
    Perhaps we're confusing thread pools and thread factories here. Are you interested in the latter only? In this case, subclass DefaultThreadFactory, which is used to create threads in a pool when needed, and provides naming of the threads (e.g. OOB-Thread11). I don't know if JSR 236 can be used to replace thread pools. As long as they define an Executor, things should work. – Bela Ban Nov 26 '15 at 17:27
  • The injected factory should be used no matter whether a node is coordinator, or not. Do you have some sample code that shows what goes wrong? – Bela Ban Dec 04 '15 at 14:07
  • Hi Bela thanks for replying...i see that factories get overridden but the behavior changes .. to be noted I am using FILE_PING for discovery and after replacing the factories ..nodes cannot connect with each other and a new cluster gets created every time a new node is added ... second problem which I see is that timer thread factory is not getting overridden ... I get this warning 10 times and then a new cluster gets created ..... org.jgroups.protocols.pbcast.ClientGmsImpl joinInternal WARNING: 31430: JOIN(31430) sent to 14136 timed out (after 2000 ms), on try 1 ... – user666 Dec 07 '15 at 15:26
  • I don't know the CommonJ lib, but all you need to return is a thread on which I can call isAlive() etc. I suggest package your code up into a compilable project that I can run to understand what you're trying to do. – Bela Ban Dec 10 '15 at 15:23
  • Hi bela ,,, thanks again for replying... we will try to put the code in git ...share it with you .... – user666 Dec 11 '15 at 10:31