You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Simon Raess <co...@gmx.ch> on 2006/03/06 21:49:50 UTC

Thread Model

hi

I have some question related to the threading model used by MINA.  
I've read the FAQ entry titled "Do I need to make my IoHandler thread- 
safe?", but was still a bit confused. So I've built a simple sample  
application.

The server checks how many threads are executing the code of the  
messageReceived method of the IoHandler. The client sends a lot of  
messages to the server. To simulate a long running task, the  
messageReceived method of the server contains a Thread.sleep.

Without adding any filter (in particular the ThreadPoolFilter, of  
course), the messageReceived method of the server IoHandler is  
executed by just one thread at a time (in fact, always the same  
thread). The overall throughput of the server is low (the server was  
sleeping most of the time...).

After adding a ThreadPool filter the situation changed. The IoHandler  
messageReceived method is called by more than one thread at a time  
(server-side). However, the method is called by only one thread at a  
time for a particular session.

What I find a bit strange is that on the server-side, there is only  
one IoHandler for all the sessions. Therefore it is unsafe to use any  
instance variables inside handlers (that is, without proper  
synchronization). I guess that's what is meant with "shared resource"  
in the FAQ. To achieve thread safety, the state should be stored as  
session attributes (correct?) or the access would have to be properly  
synchronized.

On the client side, it is possible to specify a separate IoHandler  
for each session. Wouldn't it be more natural to have the possibility  
to store state in the handler itself? On the server, this would  
require to have a separate IoHandler for each session. What do you  
think?

Simon

Re: Thread Model

Posted by Simon Raess <co...@gmx.ch>.
On 07.03.2006, at 15:59, Niklas Therning wrote:

> peter royal wrote:
>
>>>
>>> Yes, I didn't think about that possibility. But why not have   
>>> something like the following:
>>>
>>>   IoAcceptor acceptor = ...;
>>>   IoHandlerFactory factory = ...;
>>>   acceptor.accept(address, factory);
>>>
>>> where IoHandlerFactory is an interface that has the  
>>> responsibility  to create IoHandlers. This factory would be used  
>>> by the acceptor to  create an IoHandler whenever a new session is  
>>> accepted.
>>>
>>> This way, both the client-side and server-side IoHandler could   
>>> safely use state in instance variables. This seems more  
>>> consistent  to me.
>> I guess it just depends on what is the more common case. In my   
>> experience, I have no problems with everything flowing into a  
>> single  IoHandler on the server side. So I would want an  
>> IoHandlerFactory  that just returned the same instance each time.  
>> Whichever way it is  implemented, I think it would be a valuable  
>> contribution to MINA.
>> -pete
>
> If the handler is per session there's no need to pass in the  
> session in all methods, is it? IMO it would be nicer to have a new  
> interface:
>
> interface SingleSessionIoHandler {
>   void sessionOpened();
>   void messageReceived(Object message);
>   void sessionClosed();
>   ...
> }
>
> implementation of this interface would typically store the session  
> as an instance variable.
>
> The factory interface would look like:
>
> interface SingleSessionIoHandlerFactory {
>   SingleSessionIoHandler create(IoSession session);
> }
>
> To achieve this in MINA you could implement a special IoHandler  
> which delegates to a SingleSessionIoHandler which it gets from the  
> session:
>
> public class SingleSessionIoHandlerDelegate implements IoHandler {
>   SingleSessionIoHandlerFactory factory;
>   SingleSessionIoHandlerDelegate(SingleSessionIoHandlerFactory  
> factory){
>     this.factory = factory;
>   }
>   void sessionCreated(IoSession session) {
>     SingleSessionIoHandler handler = factory.create(session);
>     session.setAttribute("handler", handler);
>   }
>   void sessionOpened(IoSession session) {
>     SingleSessionIoHandler handler = session.getAttribute("handler");
>     handler.sessionOpened();
>   }
>   void messageReceived(IoSession session, Object message) {
>     SingleSessionIoHandler handler = session.getAttribute("handler");
>     handler.messageReceived(message);
>   }
>   ...
> }
>
> To create an acceptor you would simply do:
>
> IoAcceptor acceptor = ...;
> SingleSessionIoHandlerFactory  factory = ...;
> acceptor.accept(address, new SingleSessionIoHandlerDelegate(factory));
>
> My point is that there's no need to modify the IoAcceptor interface  
> to support this kind of behaviour. I see no harm in including  
> something like this in MINA. Simon, if you have a patch please add  
> it to JIRA and we'll consider it.
>

OK. I'll try to find some time to implement what you've suggested.

Thanks!
Simon




Re: Thread Model

Posted by Niklas Therning <ni...@trillian.se>.
peter royal wrote:

>>
>> Yes, I didn't think about that possibility. But why not have  
>> something like the following:
>>
>>   IoAcceptor acceptor = ...;
>>   IoHandlerFactory factory = ...;
>>   acceptor.accept(address, factory);
>>
>> where IoHandlerFactory is an interface that has the responsibility  to 
>> create IoHandlers. This factory would be used by the acceptor to  
>> create an IoHandler whenever a new session is accepted.
>>
>> This way, both the client-side and server-side IoHandler could  safely 
>> use state in instance variables. This seems more consistent  to me.
> 
> 
> I guess it just depends on what is the more common case. In my  
> experience, I have no problems with everything flowing into a single  
> IoHandler on the server side. So I would want an IoHandlerFactory  that 
> just returned the same instance each time. Whichever way it is  
> implemented, I think it would be a valuable contribution to MINA.
> -pete
> 

If the handler is per session there's no need to pass in the session in 
all methods, is it? IMO it would be nicer to have a new interface:

interface SingleSessionIoHandler {
   void sessionOpened();
   void messageReceived(Object message);
   void sessionClosed();
   ...
}

implementation of this interface would typically store the session as an 
instance variable.

The factory interface would look like:

interface SingleSessionIoHandlerFactory {
   SingleSessionIoHandler create(IoSession session);
}

To achieve this in MINA you could implement a special IoHandler which 
delegates to a SingleSessionIoHandler which it gets from the session:

public class SingleSessionIoHandlerDelegate implements IoHandler {
   SingleSessionIoHandlerFactory factory;
   SingleSessionIoHandlerDelegate(SingleSessionIoHandlerFactory factory){
     this.factory = factory;
   }
   void sessionCreated(IoSession session) {
     SingleSessionIoHandler handler = factory.create(session);
     session.setAttribute("handler", handler);
   }
   void sessionOpened(IoSession session) {
     SingleSessionIoHandler handler = session.getAttribute("handler");
     handler.sessionOpened();
   }
   void messageReceived(IoSession session, Object message) {
     SingleSessionIoHandler handler = session.getAttribute("handler");
     handler.messageReceived(message);
   }
   ...
}

To create an acceptor you would simply do:

IoAcceptor acceptor = ...;
SingleSessionIoHandlerFactory  factory = ...;
acceptor.accept(address, new SingleSessionIoHandlerDelegate(factory));

My point is that there's no need to modify the IoAcceptor interface to 
support this kind of behaviour. I see no harm in including something 
like this in MINA. Simon, if you have a patch please add it to JIRA and 
we'll consider it.

/Nikals

Re: Thread Model

Posted by peter royal <pr...@apache.org>.
On Mar 7, 2006, at 1:10 AM, Simon Raess wrote:
> On 06.03.2006, at 22:02, peter royal wrote:
>
>> On Mar 6, 2006, at 3:49 PM, Simon Raess wrote:
>>> On the client side, it is possible to specify a separate  
>>> IoHandler for each session. Wouldn't it be more natural to have  
>>> the possibility to store state in the handler itself? On the  
>>> server, this would require to have a separate IoHandler for each  
>>> session. What do you think?
>>
>> This can certainly be achieved with the current architecture..  
>> What you will want is an IoHandler that creates a delegate every  
>> time a new session is established on the server-side, and then the  
>> delegate would just forward events as necessary to the delegate.
>> -pete
>>
>
> Yes, I didn't think about that possibility. But why not have  
> something like the following:
>
>   IoAcceptor acceptor = ...;
>   IoHandlerFactory factory = ...;
>   acceptor.accept(address, factory);
>
> where IoHandlerFactory is an interface that has the responsibility  
> to create IoHandlers. This factory would be used by the acceptor to  
> create an IoHandler whenever a new session is accepted.
>
> This way, both the client-side and server-side IoHandler could  
> safely use state in instance variables. This seems more consistent  
> to me.

I guess it just depends on what is the more common case. In my  
experience, I have no problems with everything flowing into a single  
IoHandler on the server side. So I would want an IoHandlerFactory  
that just returned the same instance each time. Whichever way it is  
implemented, I think it would be a valuable contribution to MINA.
-pete

-- 
proyal@apache.org - http://fotap.org/~osi



Re: Thread Model

Posted by Simon Raess <co...@gmx.ch>.
On 06.03.2006, at 22:02, peter royal wrote:

> On Mar 6, 2006, at 3:49 PM, Simon Raess wrote:
>> On the client side, it is possible to specify a separate IoHandler  
>> for each session. Wouldn't it be more natural to have the  
>> possibility to store state in the handler itself? On the server,  
>> this would require to have a separate IoHandler for each session.  
>> What do you think?
>
> This can certainly be achieved with the current architecture.. What  
> you will want is an IoHandler that creates a delegate every time a  
> new session is established on the server-side, and then the  
> delegate would just forward events as necessary to the delegate.
> -pete
>

Yes, I didn't think about that possibility. But why not have  
something like the following:

   IoAcceptor acceptor = ...;
   IoHandlerFactory factory = ...;
   acceptor.accept(address, factory);

where IoHandlerFactory is an interface that has the responsibility to  
create IoHandlers. This factory would be used by the acceptor to  
create an IoHandler whenever a new session is accepted.

This way, both the client-side and server-side IoHandler could safely  
use state in instance variables. This seems more consistent to me.

Simon

Re: Thread Model

Posted by peter royal <pr...@apache.org>.
On Mar 6, 2006, at 3:49 PM, Simon Raess wrote:
> On the client side, it is possible to specify a separate IoHandler  
> for each session. Wouldn't it be more natural to have the  
> possibility to store state in the handler itself? On the server,  
> this would require to have a separate IoHandler for each session.  
> What do you think?

This can certainly be achieved with the current architecture.. What  
you will want is an IoHandler that creates a delegate every time a  
new session is established on the server-side, and then the delegate  
would just forward events as necessary to the delegate.
-pete

-- 
proyal@apache.org - http://fotap.org/~osi