On 2/11/10 7:54 AM, Julien Vermillard wrote:
Le Wed, 10 Feb 2010 13:28:11 -0800,
"Alan D. Cabrera"<[email protected]> a écrit :
On Feb 4, 2010, at 4:53 AM, Emmanuel Lecharny wrote:
I have reviewed the way we use the Selector in MINA 2.0. Here are
some of the thoughts I have about teh way we use them for Sockets :
We currently have a system built on top of three elements :
- IoAcceptor on the server side
- IoConnector on the client side
- IoProcessor which are processing the messages received or sent
IoAcceptor and IoConnector are just two sides of the same coin : a
IoService. The only difference is that the Connector initiates the
communication.
Nio Sockets
----------------
In order to deal with incoming connections, the IoAcceptor uses a
Selector on which are registered the ServerSocketChannel for the
OP_ACCEPT event. On the client side, we have the same Selector but
the ServerSocket is registered for the OP_CONNECT event.
In both case, once the session is connected/accepted, the
associated Channel is attached to another Selector, itself
associated with an IoProcessor.
Here, I'm questioning the fact that we use more than one Selector
to handle connect/accept and read/write operations. The select()
operation is not specially costly, even if it does a lot of things :
- deregister the canceled channels
- each channel which has had some operation since the last select
is put to a set of selected keys
- deregister the canceled channels again (for channel which has
been canceled while the step 2 was processed)
- return the number of keys found ready in step 2
but all in all, this is a fast operation, as it just reads some
bit fields to determinate if something has changed since the last
select. Even if we have one million registered keys in the
selector, first the number of active channel will be low, and
second the processing time for this step is very minimal compared
to the application processing time.
Now, wouldn't it be better to have only one selector, and then
dispatch the tasks to some processor?
On the server side, we have to deal with :
- newly added sessions
- recently closed sessions
- incoming data
- outgoing data
On the client side, we have to deal with :
- newly connected sessions
- recently closed sessions
- incoming data
- outgoing data
each of those tasks can be processed by a separate thread selected
in a thread pool. IMO, it may be better than the current
architecture where we have a pool of IoProcessor, each one of them
having its own Selector, and no thread to process the events. For
instance, if we have 3 IoProcessor (the default value for a dual
core processor), then we can only process 3 events in parallel.
Pretty inefficient...
I tried to follow the code for IoProcessor and my brain hurts. :)
Did I read correctly that the sessions are partitioned between N
IoProcessors? If so, seems kinda odd and I agree, what you propose
seems more straightforward.
Regards,
Alan
Now you understand the pain of maintaining this spaghetti. Last bug
proved it well. I think Emm still feel the pain.
It's behaving equals or better, I agree the code will be a lot simpler
and put NIO crap in a corner.
I would ad that reading
http://weblogs.java.net/blog/2006/07/07/tricks-and-tips-nio-part-iii-thread-or-not-thread
could give some clues about what to do and what not to do.
Of course, we can do our own experimentation, but we can also trust
those we *know* they know what they are talking about :)
--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com