You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Maciek Stachowiak <ma...@yahoo.ca> on 2007/11/17 21:12:47 UTC

Question regarding threading

Hello Tristan and everyone,

Firstly I wanted to say that what you guys have here is great. About a year
ago I was looking for a NIO framework of some kind and had no luck finding
anything so I ended up writing my own. Unfortunatly, there were many
problems and fringe cases that plagued my code so I was really relieved when
I found Mina.

Basically I'm writing a server with many continuous connections open at the
same time (approx 7,000, eventually more), I need every connection to be
able to send a request and receive a response from the server within a
reasonable amount of time. My old framework would receive any requests and
queue them up. A separate process "SchedulingThread" would run and pass off
any scheduled jobs in a roundrobin fashion into a "WorkerThreads" queue
(pool of perhaps 10 "WorkerThreads"). The "WorkerThreads" would then process
the job and queue up any responses. Being a relative novice when it comes to
server design I figured this kind of model would allow me to get the most
out of my machines resources. Anyway, I'm sorta trying to mimic (to a
degree) this kind of design using MINA...

Since I haven't found an example of this kind of "multi thread" setup I'm
working off the "Configuring Thread Model" doc in the "Advanced Topic"
section. I'm also using release 1.1.4 (would you recommend switching to
2.0?)

Anyway, this is what I currently have... obviously I sorta lost at the
moment... :)

//I'm still somewhat confused regarding what the executorservice is suppose
to do?
ExecutorService executor = ...;

IoAcceptor acceptor = new
SocketAcceptor(Runtime.getRuntime().availableProcessors() + 1,
executor.newCachedThreadPool());
IoAcceptorConfig config = new SocketAcceptorConfig();

//Disabled ThreadModel as suggested in the documentation
config.setThreadModel(ThreadModel.MANUAL);

DefaultIoFilterChainBuilder chain = config.getFilterChain();
chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
chain.addLast("threadPool", new
ExecutorFilter(executor.newCachedThreadPool());

//WorkerHandler extends IoHandlerAdapter, should I be doing something here
(implementing runnable in the WorkerHandler?) since this is the workhorse of
the server and I'll probably want mutliple threads running an processing...
acceptor.bind(new InetSocketAddress(PORT), new WorkerHandler(), config);

//How would I unbind?
acceptor.unbind(...);
executor.shutdown();

If anyone could point me in the right direction or better yet show me an
example I would really appreciate it... thanks ahead of time... and you guys
have something really cool here... 
-- 
View this message in context: http://www.nabble.com/Question-regarding-threading-tf4827942s16868.html#a13812955
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: Question regarding threading

Posted by Maciek Stachowiak <ma...@yahoo.ca>.
Hi Maarten,

As you can see I don't have that much experience when it comes to server
design :) After building up my own framework and running into all sorts of
unexpected problems I'm really likeing this API... Thank you Trustin and
Maarten...
-- 
View this message in context: http://www.nabble.com/Question-regarding-threading-tf4827942s16868.html#a13861831
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: Question regarding threading

Posted by Maarten Bosteels <mb...@gmail.com>.
Hello Maciek,

On Nov 20, 2007 5:01 PM, Maciek Stachowiak <ma...@yahoo.ca>
wrote:

>
> Hey Trustin,
>
> Oh wow... so your saying each individual IoSession can "concurrently" use
> required code from the initial IoHandler instance? That's pretty amazing
> if
> that's the case...


It is not so uncommon to have a single instance handle multiple
requests/sessions at the same time.
By default, a servlet container will also instantiate one instance of your
servlet(s) and use it concurrently for multiple requests.


> would I have to synchronize every method in my IoHandler
> (I'm guessing not, but I just want to ask to make sure)... But I would
> imagine that I need to synchronize any common data structure (i.e. hashmap
> that contains all my IoSession objects), correct?


Yes, all access to shared data structures should be properly synchronized.
Please note that you can use IoService.getManagedSessions to get all
IoSessions

http://mina.apache.org/report/1.1/apidocs/org/apache/mina/common/IoService.html#getManagedSessions(java.net.SocketAddress)


> Also would you recommend
> creating and implementing these data structures in the same class which
> extends IoHandlerAdaptor?


That's up to you really. If you have a fair amount of business logic, I
would put that logic in separate classes, independent of Mina.

Maarten

>
> --
> View this message in context:
> http://www.nabble.com/Question-regarding-threading-tf4827942s16868.html#a13859789
> Sent from the Apache MINA Support Forum mailing list archive at Nabble.com
> .
>
>

Re: Question regarding threading

Posted by Maciek Stachowiak <ma...@yahoo.ca>.
Hey Trustin,

Oh wow... so your saying each individual IoSession can "concurrently" use
required code from the initial IoHandler instance? That's pretty amazing if
that's the case... would I have to synchronize every method in my IoHandler
(I'm guessing not, but I just want to ask to make sure)... But I would
imagine that I need to synchronize any common data structure (i.e. hashmap
that contains all my IoSession objects), correct? Also would you recommend
creating and implementing these data structures in the same class which
extends IoHandlerAdaptor?
-- 
View this message in context: http://www.nabble.com/Question-regarding-threading-tf4827942s16868.html#a13859789
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: Question regarding threading

Posted by Trustin Lee <tr...@gmail.com>.
Hi Maciek,

On Nov 20, 2007 5:26 AM, Maciek Stachowiak <ma...@yahoo.ca> wrote:
>
> Hi Trustin, sorry for messing up your name last time...
>
> Ok, so assuming I use MINA 2.0 (probably the best option) I found some code
> you had posted previously...
>
>         SocketAcceptor acceptor = new NioSocketAcceptor();
>         acceptor.getFilterChain().addLast("executor", new ExecutorFilter(
>             new UnorderedThreadPoolExecutor( 0, 16, 30, TimeUnit.SECONDS,
> new IoEventQueueThrottle())));
>         acceptor.setHandler(new IoHandlerAdapter() {
>             @Override
>             public void messageReceived(IoSession session, Object message)
> throws Exception {
>                 Thread.sleep(1000);
>             }
>         });
>         acceptor.setLocalAddress(new InetSocketAddress(1234));
>         acceptor.bind();
>
>
> So I just want to make sure I'm reading this right, your adding the
> UnorderedThreadPoolExecutor to the NioSocketAcceptor which will create new
> threads as needed to a maximum of 16. Your adding a handler to the Acceptor
> which I assume could be any class that extends IoHandlerAdapter. So if
> there's alot of traffic, instances of the IoHandlerAdapter will be called
> into service as needed? Is there any rule of thumb for corePoolSize and
> maximumPoolSize? I'm a little shady regarding the keepAliveTime and
> IoEventQueueThrottle() still too...

Just one instance of IoHandler will handle all incoming connections
into the acceptor.  However, this doesn't relate to scalability at all
because your IoHandler implementation will be invoked with IoSession
instance so it's a kind of stateless.

Regarding the number of poolSize properties, You will have to
experiment by yourself because it's different between environments.
I'd suggest 0 as corePoolSize and more than 10 seconds as
keepAliveTime.

IoEventQueueThrottle is optional.  It is used to limit the number of
queued events to prevent OutOfMemoryError.  You will have to specify a
proper threshold as its constructor parameter instead of the default
value.  Actually I don't even remember what default value was for now.
:D

HTH,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP Key ID: 0x0255ECA6

Re: Question regarding threading

Posted by Maciek Stachowiak <ma...@yahoo.ca>.
Hi Trustin, sorry for messing up your name last time...

Ok, so assuming I use MINA 2.0 (probably the best option) I found some code
you had posted previously...

        SocketAcceptor acceptor = new NioSocketAcceptor();
        acceptor.getFilterChain().addLast("executor", new ExecutorFilter( 
            new UnorderedThreadPoolExecutor( 0, 16, 30, TimeUnit.SECONDS,
new IoEventQueueThrottle())));
        acceptor.setHandler(new IoHandlerAdapter() {
            @Override
            public void messageReceived(IoSession session, Object message)
throws Exception {
                Thread.sleep(1000);
            }
        });
        acceptor.setLocalAddress(new InetSocketAddress(1234));
        acceptor.bind();


So I just want to make sure I'm reading this right, your adding the
UnorderedThreadPoolExecutor to the NioSocketAcceptor which will create new
threads as needed to a maximum of 16. Your adding a handler to the Acceptor
which I assume could be any class that extends IoHandlerAdapter. So if
there's alot of traffic, instances of the IoHandlerAdapter will be called
into service as needed? Is there any rule of thumb for corePoolSize and
maximumPoolSize? I'm a little shady regarding the keepAliveTime and
IoEventQueueThrottle() still too...
-- 
View this message in context: http://www.nabble.com/Question-regarding-threading-tf4827942s16868.html#a13844579
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: Question regarding threading

Posted by Trustin Lee <tr...@gmail.com>.
On Nov 18, 2007 5:12 AM, Maciek Stachowiak <ma...@yahoo.ca> wrote:
> Hello Tristan and everyone,

Hi Maciek, I am Trustin.  :)

> Firstly I wanted to say that what you guys have here is great. About a year
> ago I was looking for a NIO framework of some kind and had no luck finding
> anything so I ended up writing my own. Unfortunatly, there were many
> problems and fringe cases that plagued my code so I was really relieved when
> I found Mina.

Glad that you are here finally, and I hope you enjoy this framework.

> Basically I'm writing a server with many continuous connections open at the
> same time (approx 7,000, eventually more), I need every connection to be
> able to send a request and receive a response from the server within a
> reasonable amount of time. My old framework would receive any requests and
> queue them up. A separate process "SchedulingThread" would run and pass off
> any scheduled jobs in a roundrobin fashion into a "WorkerThreads" queue
> (pool of perhaps 10 "WorkerThreads"). The "WorkerThreads" would then process
> the job and queue up any responses. Being a relative novice when it comes to
> server design I figured this kind of model would allow me to get the most
> out of my machines resources. Anyway, I'm sorta trying to mimic (to a
> degree) this kind of design using MINA...
>
> Since I haven't found an example of this kind of "multi thread" setup I'm
> working off the "Configuring Thread Model" doc in the "Advanced Topic"
> section. I'm also using release 1.1.4 (would you recommend switching to
> 2.0?)

Isn't it an acceptor with an ExecutorFilter inserted?  Am I missing something?

> Anyway, this is what I currently have... obviously I sorta lost at the
> moment... :)
>
> //I'm still somewhat confused regarding what the executorservice is suppose
> to do?
> ExecutorService executor = ...;
>
> IoAcceptor acceptor = new
> SocketAcceptor(Runtime.getRuntime().availableProcessors() + 1,
> executor.newCachedThreadPool());
> IoAcceptorConfig config = new SocketAcceptorConfig();
>
> //Disabled ThreadModel as suggested in the documentation
> config.setThreadModel(ThreadModel.MANUAL);
>
> DefaultIoFilterChainBuilder chain = config.getFilterChain();
> chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
> chain.addLast("threadPool", new
> ExecutorFilter(executor.newCachedThreadPool());
>
> //WorkerHandler extends IoHandlerAdapter, should I be doing something here
> (implementing runnable in the WorkerHandler?) since this is the workhorse of
> the server and I'll probably want mutliple threads running an processing...
> acceptor.bind(new InetSocketAddress(PORT), new WorkerHandler(), config);
>
> //How would I unbind?
> acceptor.unbind(...);
> executor.shutdown();
>
> If anyone could point me in the right direction or better yet show me an
> example I would really appreciate it... thanks ahead of time... and you guys
> have something really cool here...

If you added an ExecutorFilter, you don't need to use an extra thread
pool for your tasks.  However, ExecutorFilter in 1.x always maintains
the order of received messages, which means one connection uses only
one thread at the same time.  To disable event ordering:

1) Use MINA 2.0 and UnorderedThreadPoolExecutor
2) Use MINA 1.x and implement your own IoFilter.
3) Use MINA 1.x, don't use ExecutorFilter but call executor in your
IoHandler implementation.

HTH,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP Key ID: 0x0255ECA6