> Thanks for the detailed explanation, Emmanuel.  I actually understood most
> of this pretty well already, though, as I've been digging through the code
> quite extensively to try to understand what was going on.

Hmmm... Sounds like we may have a new committer sooner or later ;)

>
>
> But a) if I'm reading the code correctly, it looks like what you wrote is
> not exactly correct,

probably. It was from the top of my head, after two weeks without
looking at the code.

and b) I'm not sure you understood what I was trying to
> communicate in my last message - that the way MINA is coded, having a thread
> pool executor for write operations is completely useless, since the write
> thread pool will *never* get used to actually perform socket IO.

That was exactly what I had in mind. But maybe I didn't expressed it
correctly. Once you went throw the Executor filter, there is nothing
you can do to spread the load anymore. That's a pity, btw ...

>
> Let me explain.  Let's say you have a filter chain like so:
>
>                DefaultIoFilterChainBuilder filterChainBuilder =
> protocolAcceptor.getFilterChain();
>                filterChainBuilder.addLast("codec", new
> ProtocolCodecFilter(codecFactory));
>                threadPool = new OrderedThreadPoolExecutor();
>                filterChainBuilder.addLast("writer thread pool", new
> ExecutorFilter(threadPool, IoEventType.WRITE));
>                protocolAcceptor.setHandler(protocolHandler);
>
> So the intention here is that after the codec does its work (i.e., processes
> an incoming message and generates a response) the actual write operation
> (i.e., actually physically writing the IoBuffer bytes out to the socket)
> should get performed in a threadPool thread.

More precisely, the IoHandler will process the request after a thread
has been selected by the ThreadPoolExecutor.


> But that does not happen.  Instead, the write operation gets performed in
> the IoProcessor thread.

That's not what happen. In fact, of course, the IoProcessor *is*
processing the write, _but_ the thread selected by the Executor will
do all the processing before (including the encoding), and then
enqueue the result for the IoProcessor to deal with it later.

  And then, later, although the filter chain does
> invoke filterWrite() and messageSent() on the ExecutorFilter, that winds up
> essentially being a NO-OP, since there is nothing downstream from the
> executor filter that is doing any socket IO.  So the whole concept of a
> writer thread pool is not possible to implement the way MINA is coded.

I have to double check that. It may depend on where you put the
executor filter in the chain(ie before or after the codec filter).
Now, to be frank, I think that there is something wrong in the way
MINA chain works. I would rather have 2 chains (one upstream, one
downstream) with the possibility to have more than one executor
filter.

> I guess what I'm finding unexpected about the way MINA is coded is this:
>
> I would expect that messages/method-calls would traverse down the filter
> chain and then, finally, after the final (tail) filter in the chain is
> executed, then MINA would write the output out to the socket.

Well, you have to go through the chain again, as you may have to
encode the message, or such processing.

>
> But according to DefaultIoFilterChain.HeadFilter, it looks like the *head*
> of the filter chain, not the tail, is what's writing the output out to the
> socket:

Yes, it sounds strange, but it makes sense (somehow). The requests are
injected into the Head, processed down the chain up to the Tail, and
back. Again, that does not sounds a very good idea to me, as it's
confusing. With two chains, that would be easier to understand. But in
any case, this is plain normal.

>    private class HeadFilter extends IoFilterAdapter {
>       �...@suppresswarnings("unchecked")
>       �...@override
>        public void filterWrite(NextFilter nextFilter, IoSession session,
>                WriteRequest writeRequest) throws Exception {
> ...
>            s.getWriteRequestQueue().offer(s, writeRequest);
>
>
>
> I don't quite understand this.  And as a matter of fact, it seems like this
> could cause some VERY unexpected behavior.

No, there are no risk of unexpected behavior. Just a risk that users
get confused (should we name that a 'risk' when it's obviously already
the case ?)


> For example, say I wanted to add a
> org.apache.mina.filter.util.WriteRequestFilter at the end of my filter chain
> which alters the outgoing message before it gets sent.  But this would not
> work!  Since the message gets queued for send at the *head* of the filter
> chain, any changes I make to the message at the tail of the chain would have
> no effect.

Remember that the chain is processed in both ways : from Head to Tail
(incoming requests) and then from Tail to Head (session.write()).


> In any case, the bottom line is:  it looks like my efforts to try to get
> MINA to send messages out through the socket in a different thread cannot be
> successful.  No matter how I configure things, MINA will always do the
> socket IO in the IoAcceptor thread.

That's plain normal, as the selector is handled in the IoProcessor.

>
> It's easy to verify this, by the way:  Try adding a "write thread pool" to
> your filter chain like I described above.  Then, in the messageReceived()
> method of your protocol handler, where you write your response, include the
> following code:
>
>                WriteFuture writeFuture = session.write(responseStr);
>                writeFuture.addListener(
>                        new IoFutureListener<WriteFuture>() {
>                                public void operationComplete(WriteFuture
> future) {
>                                        System.out.println("message write
> occurred in thread: "+Thread.currentThread().getName());
>                                }
>                        }
>                );
>
> On my machine, the output always occurs in thread "NioProcessor-1", instead
> of one of the executor filter threads.
>
>
> I hope I was clearer this time and that this makes some sense to you.
>
> Can you shed any light on what's happening here and/or why the write request
> is getting queued in the head filter?

Did I succeeded in bringing a faint light on the obscure side of MINA ?

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com

Reply via email to