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