Doing some performance tests on my client/server application with two 2-CPUs machines I see that adding two thread pools (one for MESSAGE_RECEIVED and one for WRITE) application performances lower. Of course it depends from my application and test machines but it shows that using thread pools doesn't always brings benefit with it.

I wonder if performances reduction in case of thread pools executors depends on some kind of overhead spreading work among threads.

Cheers

Emmanuel Lecharny wrote:
David Rosenstrauch wrote:
Hmmm .... this seemed to solve the problem for me:

readerThreadPool = new OrderedThreadPoolExecutor();
filterChain.addLast("readExecutor", new ExecutorFilter(readerThreadPool, IoEventType.MESSAGE_RECEIVED));
filterChain.addLast("codec", new ProtocolCodecFilter(codecFactory));
writerThreadPool = new OrderedThreadPoolExecutor();
filterChain.addLast("writeExecutor", new ExecutorFilter(writerThreadPool, IoEventType.WRITE));


... and then on session close:

readerThreadPool.shutdown();
writerThreadPool.shutdown();


I'm guessing that what going on previously is that when I was using the single thread pool I wasn't explicitly specifying event types that the thread pool should be used for, and so it was also being used to handle events like session closed or (in your case) exception caught. And since the thread pool was already shut down, it wasn't able to handle those events.

That said, I'm a bit unclear about how this thread pool stuff works in Mina 2.0. Is it the code I wrote above considered good practice? i.e.:

* is it sensible to have a thread pool handling MESSAGE_RECEIVED, and WRITE?
It depends on how expensive those operations are. The best would be to do some stress test, and see if yur program is bound by the CPU, by the bandwith or by the tasks handled in the filters or handler for received or write messages. Typically, if encoding or decoding a message is a costly operation, without an executor on a N-way CPU server, that might be a contention.

* is it sensible to NOT have the thread pool handling other event types? (e.g., session closed and exception)
Again, it will depend on how expensive those operations are. Usually, I don't think it works using a thread from a pool for them.

* Can someone explain why the DEFAULT_EVENT_SET in ExecutorFilter is defined as it is? i.e.:
    private static IoEventType[] DEFAULT_EVENT_SET = new IoEventType[] {
        IoEventType.EXCEPTION_CAUGHT,
        IoEventType.MESSAGE_RECEIVED,
        IoEventType.MESSAGE_SENT,
        IoEventType.SESSION_CLOSED,
        IoEventType.SESSION_IDLE,
        IoEventType.SESSION_OPENED
    };
Why are all these events included?

Perhaps someone more knowledgeable about Mina can offer an explanation.
My understanding is that the Executor filter just adds an executor in the chain which will be used to spread the load on many threads. This is an optimization, rather than something you need to use. If you don't use it, your program will work fine.

Now, considering that all your filters are thread safe (and the codec is probably the part which has to be double checked, as it's the filter user's will write), you will be safe whatever you do.

If you have a lot of work to do when handling a SESSION_CLOSED or a SESSION_OPENED event (for instance, you need to open/close a database connection), then using an executor for those events might be better.

The default is to handle all the events, I have no idea if it's a good politic or not. One might object that handling only MESSAGE_RECEIVED and MESSAGE_SENT is strange, as there are other events available. Anyway, this is configurable, so ...

My 2 cts...


--

*Patrizio Munzi*
Product Specialist
Viale Bruno Buozzi, 19 - 00197 Roma (Italy)
tel: +39 06 4543 3540
fax: +39 06 4543 3587
mobile: +39 393 7195 164
mail: [email protected] <mailto:[email protected]>
web: http://www.eris4.com <http://www.eris4.com/>
skype: eris4_munzi <skype:eris4_munzi?add>

Reply via email to