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...
--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org