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>