You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Emmanuel Lecharny <el...@gmail.com> on 2008/11/10 14:56:27 UTC

[MINA 2 new chain] Some feedback

Hi guys,

I'm still doing some experiment with the new chain (in mina-new-chain2 
branch). It's not totally satisfactory, mainly for two reasons :
- I have used a List to store the filters, so I have to propagate an 
integer index to jump from one filter to another. This is a bit ugly, as 
you have inex+1 all over the code. I will move to what was suggested by 
Steve Ulrich (passing a ChainIterator instead of an index will mask the 
ugly +1).
- The current MINA code is so damn complex that it makes it an order of 
magnitude more complicated to fix than to rewrite it, but this is not 
something I want to jump in, yet. As an example, here is the stack you 
get when you receive a message and send back a response (just for you to 
realize how insane is the current code ...). And we only have three 
filters : mdc, codec and logging.

AbstractPollingIoProcessor$Processor.run()
  NioProcessor(AbstractPollingIoProcessor<T>).process()
    NioProcessor(AbstractPollingIoProcessor<T>).process(T)
      NioProcessor(AbstractPollingIoProcessor<T>).read(T)
      | DefaultIoFilterChain.fireMessageReceived(java.lang.Object)
      |   
DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, 
IoSession, Object)
      |     
DefaultIoFilterChain$HeadFilter(IoFilterAdapter).messageReceived(IoFilter$NextFilter, 
IoSession, Object)
      |       
DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)
      |         
DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, 
IoSession, Object)   
      |           
MdcInjectionFilter(CommonEventFilter).messageReceived(IoFilter$NextFilter, 
IoSession, Object)
      |             MdcInjectionFilter.filter(IoFilterEvent)
      |               IoFilterEvent.fire()
      |                 
DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)
      |                   
DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, 
IoSession, Object)
      |                     
ProtocolCodecFilter.messageReceived(IoFilter$NextFilter, IoSession, Object)
      |                     | TextLineDecoder.decode(IoSession, 
IoBuffer, ProtocolDecoderOutput)
      |                     |   
TextLineDecoder.decodeAuto(TextLineDecoder$Context, IoSession, IoBuffer, 
ProtocolDecoderOutput)
      |                     | <-+
      |                     | 
ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush()
      |                     |   
DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)
      |                     |     
DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, 
IoSession, Object)
      |                     |       
LoggingFilter.messageReceived(IoFilter$NextFilter, IoSession, Object)
      |                     |         
DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)   
      |                     |           
DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, 
IoSession, Object)   
      |                     |             
DefaultIoFilterChain$TailFilter.messageReceived(IoFilter$NextFilter, 
IoSession, Object)   
      |                     |               
ChatProtocolHandler.messageReceived(IoSession, Object)
      |                     |                 
ChatProtocolHandler.broadcast(String)
      |                     |                   
NioSocketSession(AbstractIoSession).write(Object)   
      |                     |                     
NioSocketSession(AbstractIoSession).write(Object, SocketAddress)
      |                     |                       
DefaultIoFilterChain.fireFilterWrite(WriteRequest)
      |                     |                         
DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)
      |                     |                           
DefaultIoFilterChain$TailFilter.filterWrite(IoFilter$NextFilter, 
IoSession, WriteRequest)
      |                     |                             
DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
      |                     |                               
DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)
      |                     |                                 
LoggingFilter(IoFilterAdapter).filterWrite(IoFilter$NextFilter, 
IoSession, WriteRequest)
      |                     |                                   
DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
      |                     |                                     
DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)
      |                     |                                       
ProtocolCodecFilter.filterWrite(IoFilter$NextFilter, IoSession, 
WriteRequest)
      |                     |                                       | 
TextLineEncoder.encode(IoSession, Object, ProtocolEncoderOutput)
      |                     |                                       |   
ProtocolCodecFilter$ProtocolEncoderOutputImpl(AbstractProtocolEncoderOutput).write(Object)
      |                     |                                       | <-+
      |                     |                                       | 
ProtocolCodecFilter$ProtocolEncoderOutputImpl.flushWithoutFuture()
      |                     |                                       |   
DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
      |                     |                                       
|     DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)
      |                     |                                       
|       
MdcInjectionFilter(CommonEventFilter).filterWrite(IoFilter$NextFilter, 
IoSession, WriteRequest)   
      |                     |                                       
|         MdcInjectionFilter.filter(IoFilterEvent)   
      |                     |                                       
|           IoFilterEvent.fire()   
      |                     |                                       
|             DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, 
WriteRequest)
      |                     |                                       
|               
DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)   
      |                     |                                       
|                 
DefaultIoFilterChain$HeadFilter.filterWrite(IoFilter$NextFilter, 
IoSession, WriteRequest)   
      |                     |                                       
|                   SimpleIoProcessorPool<T>.flush(T)   
      |                     |                                       
|                     
NioProcessor(AbstractPollingIoProcessor<T>).flush(T)   
      |                     |                                       
|                       NioProcessor.wakeup()   
      |                     |                                       
|                     <-+
      |                     |                                       
|                   <-+
      |                     |                                       
|                 <-+
      |                     |                                       
|               <-+
      |                     |                                       
|             <-+
      |                     |                                       
|           <-+
      |                     |                                       
|         <-+
      |                     |                                       
|       <-+
      |                     |                                       
|     <-+
      |                     |                                       |   <-+
      |                     |                                       | <-+
      |                     |                                       | 
DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
      |                     |                                       |   
DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)
      |                     |                                       
|     CommonEventFilter).filterWrite(IoFilter$NextFilter, IoSession, 
WriteRequest)
      |                     |                                       
|       MdcInjectionFilter.filter(IoFilterEvent)
      |                     |                                       
|         IoFilterEvent.fire()
      |                     |                                       
|           DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, 
WriteRequest)   
      |                     |                                       
|             
DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, 
IoSession, WriteRequest)
      |                     |                                       
|               
DefaultIoFilterChain$HeadFilter.filterWrite(IoFilter$NextFilter, 
IoSession, WriteRequest)
      |                     |                                       
|                 SimpleIoProcessorPool<T>.flush(T)
      |                     |                                       
|                   
NioProcessor(org.apache.mina.core.polling.AbstractPollingIoProcessor<T>).flush(T)
      |                     |                                       
|                 <-+
      |                     |                                       
|               <-+
      |                     |                                       
|             <-+
      |                     |                                       
|           <-+
      |                     |                                       
|         <-+
      |                     |                                       
|       <-+
      |                     |                                       
|     <-+
      |                     |                                       |   <-+
      |                     |                                       | <-+
      |                     |                                       <-+
      |                     |                                     <-+   
      |                     |                                   <-+   
      |                     |                                 <-+   
      |                     |                               <-+   
      |                     |                             <-+   
      |                     |                           <-+   
      |                     |                         <-+   
      |                     |                       <-+   
      |                     |                     <-+   
      |                     |                   <-+   
      |                     |                 <-+   
      |                     |               <-+   
      |                     |             <-+   
      |                     |           <-+   
      |                     |         <-+   
      |                     |       <-+   
      |                     |     <-+   
      |                     |   <-+   
      |                     | <-+   
      |                     <-+   
      |                   <-+   
      |                 <-+   
      |               <-+   
      |             <-+   
      |           <-+   
      |         <-+   
      |       <-+   
      |     <-+
      |   <-+   
      | <-+   
      <-+
    <-+
  <-+
  NioProcessor(AbstractPollingIoProcessor<T>).flush(long)
    NioProcessor(AbstractPollingIoProcessor<T>).flushNow(T, long)
      NioProcessor(AbstractPollingIoProcessor<T>).writeBuffer(T, 
WriteRequest, boolean, int, long)
      | NioProcessor.write(NioSession, IoBuffer, int)  // Actually write 
data into the socket
      <-+
        NioProcessor(AbstractPollingIoProcessor<T>).fireMessageSent(T, 
WriteRequest)   
          DefaultIoFilterChain.fireMessageSent(WriteRequest)   
            
DefaultIoFilterChain.callNextMessageSent(IoFilterChain$Entry, IoSession, 
WriteRequest)   
              
DefaultIoFilterChain$HeadFilter(IoFilterAdapter).messageSent(IoFilter$NextFilter, 
IoSession, WriteRequest)   
                
DefaultIoFilterChain.callNextMessageSent(IoFilterChain$Entry, IoSession, 
WriteRequest)   
                  
MdcInjectionFilter(org.apache.mina.filter.util.CommonEventFilter).messageSent(IoFilter$NextFilter, 
IoSession, WriteRequest)   
                    MdcInjectionFilter.filter(IoFilterEvent)   
                      IoFilterEvent.fire()   
                        
DefaultIoFilterChain$EntryImpl$1.messageSent(IoSession, WriteRequest)
                          
DefaultIoFilterChain.callNextMessageSent(IoFilterChain$Entry, IoSession, 
WriteRequest)   
                            
ProtocolCodecFilter.messageSent(IoFilter$NextFilter, IoSession, 
WriteRequest)
                          <-+   
                        <-+
                      <-+
                    <-+
                  <-+
                <-+
              <-+
            <-+
          <-+
        <-+
      <-+
    <-+
  <-+
<-+

You can see that :
- for each filter, we have at least 3 lines in the stack, and we have 2 
more filters : Head and Tail, which make a total of 15 lines, before we 
reach the Handler (in fact, 16 because we go through a two-step filter, 
the MDC filter). We should be able to get it done in 4 steps, max (which 
is what I currently get, except that I still have this extra MDC step)
- The write chain is called twice : once in 
ProtocolCodecFilter$ProtocolEncoderOutputImpl.flushWithoutFuture(), for 
an extra 11 steps, and as the continuation of the write chain (which has 
already been followed into the flushWthoutFuture() method call), for 9 
extra steps. I have no f**** idea why this call is necessary, so if 
anyone has an idea, please, feel free to tell me. (In my experiment, I 
have removed this last call, and it seems to be useless, but I'm not 
100% sure). The only difference is that in the first case, we send a 
WriteRequest, when in the second case, we create a MessageSendRequest() 
object encapsulating the WriteRequest (no idea why...)
- When all this 'usefull' chaining is done, we then call the chain again 
to inform (who ???) that the message has been sent. This seems to be 
overkilling...

Ok, now, whoever thinks that this is manageable and easy to debug, you 
have to offer me a bunch of beers next year in Amsterdam, and may be 
some of those special space cakes those who created this portion of code 
must have obviously abused while coding :) !

I will commit what I came to with the new chain approach, even if it's 
not -yet- working well : I still have some issues when closing the 
session, it seems that the 'close' message does not propagate well in 
the chat sample.

I will also try to draw a short desription, with some schema, on how a 
server is initialized and session are created, with all the parallel 
threads (but the IdleThread, which is totally a waste for socket).

Thanks !

-- 
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org



Re: [MINA 2 new chain] Some feedback

Posted by Mark Webb <el...@gmail.com>.
I might need some beers just to cure the headache I get from looking
at that stack trace.

I agree that the "+1" is ugly and the ChainIterator is a much better
solution.  Would a queue work in this situation?

--Mark


On Mon, Nov 10, 2008 at 8:56 AM, Emmanuel Lecharny <el...@gmail.com> wrote:
> Hi guys,
>
> I'm still doing some experiment with the new chain (in mina-new-chain2
> branch). It's not totally satisfactory, mainly for two reasons :
> - I have used a List to store the filters, so I have to propagate an integer
> index to jump from one filter to another. This is a bit ugly, as you have
> inex+1 all over the code. I will move to what was suggested by Steve Ulrich
> (passing a ChainIterator instead of an index will mask the ugly +1).
> - The current MINA code is so damn complex that it makes it an order of
> magnitude more complicated to fix than to rewrite it, but this is not
> something I want to jump in, yet. As an example, here is the stack you get
> when you receive a message and send back a response (just for you to realize
> how insane is the current code ...). And we only have three filters : mdc,
> codec and logging.
>
> AbstractPollingIoProcessor$Processor.run()
>  NioProcessor(AbstractPollingIoProcessor<T>).process()
>   NioProcessor(AbstractPollingIoProcessor<T>).process(T)
>     NioProcessor(AbstractPollingIoProcessor<T>).read(T)
>     | DefaultIoFilterChain.fireMessageReceived(java.lang.Object)
>     |   DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry,
> IoSession, Object)
>     |
> DefaultIoFilterChain$HeadFilter(IoFilterAdapter).messageReceived(IoFilter$NextFilter,
> IoSession, Object)
>     |       DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession,
> Object)
>     |
> DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, IoSession,
> Object)       |
> MdcInjectionFilter(CommonEventFilter).messageReceived(IoFilter$NextFilter,
> IoSession, Object)
>     |             MdcInjectionFilter.filter(IoFilterEvent)
>     |               IoFilterEvent.fire()
>     |
> DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)
>     |
> DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, IoSession,
> Object)
>     |
> ProtocolCodecFilter.messageReceived(IoFilter$NextFilter, IoSession, Object)
>     |                     | TextLineDecoder.decode(IoSession, IoBuffer,
> ProtocolDecoderOutput)
>     |                     |
> TextLineDecoder.decodeAuto(TextLineDecoder$Context, IoSession, IoBuffer,
> ProtocolDecoderOutput)
>     |                     | <-+
>     |                     |
> ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush()
>     |                     |
> DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)
>     |                     |
> DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, IoSession,
> Object)
>     |                     |
> LoggingFilter.messageReceived(IoFilter$NextFilter, IoSession, Object)
>     |                     |
> DefaultIoFilterChain$EntryImpl$1.messageReceived(IoSession, Object)       |
>                     |
> DefaultIoFilterChain.callNextMessageReceived(IoFilterChain$Entry, IoSession,
> Object)       |                     |
> DefaultIoFilterChain$TailFilter.messageReceived(IoFilter$NextFilter,
> IoSession, Object)       |                     |
> ChatProtocolHandler.messageReceived(IoSession, Object)
>     |                     |
> ChatProtocolHandler.broadcast(String)
>     |                     |
> NioSocketSession(AbstractIoSession).write(Object)       |
>   |                     NioSocketSession(AbstractIoSession).write(Object,
> SocketAddress)
>     |                     |
> DefaultIoFilterChain.fireFilterWrite(WriteRequest)
>     |                     |
> DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, IoSession,
> WriteRequest)
>     |                     |
> DefaultIoFilterChain$TailFilter.filterWrite(IoFilter$NextFilter, IoSession,
> WriteRequest)
>     |                     |
> DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
>     |                     |
> DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, IoSession,
> WriteRequest)
>     |                     |
> LoggingFilter(IoFilterAdapter).filterWrite(IoFilter$NextFilter, IoSession,
> WriteRequest)
>     |                     |
> DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
>     |                     |
> DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, IoSession,
> WriteRequest)
>     |                     |
> ProtocolCodecFilter.filterWrite(IoFilter$NextFilter, IoSession,
> WriteRequest)
>     |                     |                                       |
> TextLineEncoder.encode(IoSession, Object, ProtocolEncoderOutput)
>     |                     |                                       |
> ProtocolCodecFilter$ProtocolEncoderOutputImpl(AbstractProtocolEncoderOutput).write(Object)
>     |                     |                                       | <-+
>     |                     |                                       |
> ProtocolCodecFilter$ProtocolEncoderOutputImpl.flushWithoutFuture()
>     |                     |                                       |
> DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
>     |                     |                                       |
> DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, IoSession,
> WriteRequest)
>     |                     |                                       |
> MdcInjectionFilter(CommonEventFilter).filterWrite(IoFilter$NextFilter,
> IoSession, WriteRequest)       |                     |
>                 |         MdcInjectionFilter.filter(IoFilterEvent)       |
>                   |                                       |
> IoFilterEvent.fire()       |                     |
>             |
> DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
>     |                     |                                       |
>       DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry,
> IoSession, WriteRequest)       |                     |
>                 |
> DefaultIoFilterChain$HeadFilter.filterWrite(IoFilter$NextFilter, IoSession,
> WriteRequest)       |                     |
>       |                   SimpleIoProcessorPool<T>.flush(T)       |
>             |                                       |
> NioProcessor(AbstractPollingIoProcessor<T>).flush(T)       |
>     |                                       |
> NioProcessor.wakeup()       |                     |
>               |                     <-+
>     |                     |                                       |
>           <-+
>     |                     |                                       |
>         <-+
>     |                     |                                       |
>       <-+
>     |                     |                                       |
>     <-+
>     |                     |                                       |
>   <-+
>     |                     |                                       |
> <-+
>     |                     |                                       |
> <-+
>     |                     |                                       |     <-+
>     |                     |                                       |   <-+
>     |                     |                                       | <-+
>     |                     |                                       |
> DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
>     |                     |                                       |
> DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry, IoSession,
> WriteRequest)
>     |                     |                                       |
> CommonEventFilter).filterWrite(IoFilter$NextFilter, IoSession, WriteRequest)
>     |                     |                                       |
> MdcInjectionFilter.filter(IoFilterEvent)
>     |                     |                                       |
> IoFilterEvent.fire()
>     |                     |                                       |
>   DefaultIoFilterChain$EntryImpl$1.filterWrite(IoSession, WriteRequest)
>   |                     |                                       |
>   DefaultIoFilterChain.callPreviousFilterWrite(IoFilterChain$Entry,
> IoSession, WriteRequest)
>     |                     |                                       |
>       DefaultIoFilterChain$HeadFilter.filterWrite(IoFilter$NextFilter,
> IoSession, WriteRequest)
>     |                     |                                       |
>         SimpleIoProcessorPool<T>.flush(T)
>     |                     |                                       |
>
> NioProcessor(org.apache.mina.core.polling.AbstractPollingIoProcessor<T>).flush(T)
>     |                     |                                       |
>         <-+
>     |                     |                                       |
>       <-+
>     |                     |                                       |
>     <-+
>     |                     |                                       |
>   <-+
>     |                     |                                       |
> <-+
>     |                     |                                       |
> <-+
>     |                     |                                       |     <-+
>     |                     |                                       |   <-+
>     |                     |                                       | <-+
>     |                     |                                       <-+
>     |                     |                                     <-+       |
>                     |                                   <-+       |
>             |                                 <-+       |
>   |                               <-+       |                     |
>                     <-+       |                     |
>     <-+       |                     |                         <-+       |
>                   |                       <-+       |                     |
>                     <-+       |                     |                   <-+
>       |                     |                 <-+       |
>   |               <-+       |                     |             <-+       |
>                     |           <-+       |                     |
> <-+       |                     |       <-+       |                     |
>   <-+       |                     |   <-+       |                     | <-+
>       |                     <-+       |                   <-+       |
>           <-+       |               <-+       |             <-+       |
>       <-+       |         <-+       |       <-+       |     <-+
>     |   <-+       | <-+       <-+
>   <-+
>  <-+
>  NioProcessor(AbstractPollingIoProcessor<T>).flush(long)
>   NioProcessor(AbstractPollingIoProcessor<T>).flushNow(T, long)
>     NioProcessor(AbstractPollingIoProcessor<T>).writeBuffer(T, WriteRequest,
> boolean, int, long)
>     | NioProcessor.write(NioSession, IoBuffer, int)  // Actually write data
> into the socket
>     <-+
>       NioProcessor(AbstractPollingIoProcessor<T>).fireMessageSent(T,
> WriteRequest)           DefaultIoFilterChain.fireMessageSent(WriteRequest)
>           DefaultIoFilterChain.callNextMessageSent(IoFilterChain$Entry,
> IoSession, WriteRequest)
> DefaultIoFilterChain$HeadFilter(IoFilterAdapter).messageSent(IoFilter$NextFilter,
> IoSession, WriteRequest)
> DefaultIoFilterChain.callNextMessageSent(IoFilterChain$Entry, IoSession,
> WriteRequest)
> MdcInjectionFilter(org.apache.mina.filter.util.CommonEventFilter).messageSent(IoFilter$NextFilter,
> IoSession, WriteRequest)
> MdcInjectionFilter.filter(IoFilterEvent)
> IoFilterEvent.fire()
> DefaultIoFilterChain$EntryImpl$1.messageSent(IoSession, WriteRequest)
>
> DefaultIoFilterChain.callNextMessageSent(IoFilterChain$Entry, IoSession,
> WriteRequest)
> ProtocolCodecFilter.messageSent(IoFilter$NextFilter, IoSession,
> WriteRequest)
>                         <-+                         <-+
>                     <-+
>                   <-+
>                 <-+
>               <-+
>             <-+
>           <-+
>         <-+
>       <-+
>     <-+
>   <-+
>  <-+
> <-+
>
> You can see that :
> - for each filter, we have at least 3 lines in the stack, and we have 2 more
> filters : Head and Tail, which make a total of 15 lines, before we reach the
> Handler (in fact, 16 because we go through a two-step filter, the MDC
> filter). We should be able to get it done in 4 steps, max (which is what I
> currently get, except that I still have this extra MDC step)
> - The write chain is called twice : once in
> ProtocolCodecFilter$ProtocolEncoderOutputImpl.flushWithoutFuture(), for an
> extra 11 steps, and as the continuation of the write chain (which has
> already been followed into the flushWthoutFuture() method call), for 9 extra
> steps. I have no f**** idea why this call is necessary, so if anyone has an
> idea, please, feel free to tell me. (In my experiment, I have removed this
> last call, and it seems to be useless, but I'm not 100% sure). The only
> difference is that in the first case, we send a WriteRequest, when in the
> second case, we create a MessageSendRequest() object encapsulating the
> WriteRequest (no idea why...)
> - When all this 'usefull' chaining is done, we then call the chain again to
> inform (who ???) that the message has been sent. This seems to be
> overkilling...
>
> Ok, now, whoever thinks that this is manageable and easy to debug, you have
> to offer me a bunch of beers next year in Amsterdam, and may be some of
> those special space cakes those who created this portion of code must have
> obviously abused while coding :) !
>
> I will commit what I came to with the new chain approach, even if it's not
> -yet- working well : I still have some issues when closing the session, it
> seems that the 'close' message does not propagate well in the chat sample.
>
> I will also try to draw a short desription, with some schema, on how a
> server is initialized and session are created, with all the parallel threads
> (but the IdleThread, which is totally a waste for socket).
>
> Thanks !
>
> --
> --
> cordialement, regards,
> Emmanuel Lécharny
> www.iktek.com
> directory.apache.org
>
>
>