Re: Multithreaded UDP server vs. OrderedThreadPoolExecutor
Le 9/24/13 9:47 AM, Christian Hammers a écrit : > Hello > > I've written a server for a proprietary UDP protocol that needs to answer with > exactly one packet for every incoming packet. All packets are independent from > each other so that I like to have each one handled asynchronously by a > different thread from a pool with a certain maximum size. > > So far I used this: > > FooCodec codec = new FooCodec(); // encoder and decoder in one class > InetSocketAddress local = new InetSocketAddress(port); > > acceptor = new NioDatagramAcceptor(); > acceptor.getFilterChain().addLast("executor", new > ExecutorFilter(maxThreads)); > acceptor.getFilterChain().addLast("codec", new > ProtocolCodecFilter(codec, codec)); > acceptor.setHandler(handler); > acceptor.bind(local); > > At first it seemed that each incoming UDP package, due to its stateless > nature, > creates a different Mina "session" and each Mina "session" runs in its own > thread so that the default ExecutorFilter implementation > OrderedThreadPoolExecutor is fine as I certainly don't want the session > closed > if there is still a response before it in the queue. That's not what is currently happening. MINA creates a session for each IP address, so if all your UDP messages are issued by one single machine using one IP address, then all the UDP messages will be processed by the same thread. Adding an executor in the chain just make it likely that a separate thread will process each UDP message, but the session remains shared. That explains what you see. Just get rid of the executor, and increase the number of IoProcessor, you will be able to spread the load on many threads, and each new UDP message will be completely processed before the next UDP message can start to be processed. Hope it helps. -- Regards, Cordialement, Emmanuel Lécharny www.iktek.com
Re: Multithreaded UDP server vs. OrderedThreadPoolExecutor
The first thing I would do would be to disable the executor and try again. You could be encountering some sort of deadlock. On Sep 24, 2013 12:47 PM, "Christian Hammers" wrote: > Hello > > I've written a server for a proprietary UDP protocol that needs to answer > with > exactly one packet for every incoming packet. All packets are independent > from > each other so that I like to have each one handled asynchronously by a > different thread from a pool with a certain maximum size. > > So far I used this: > > FooCodec codec = new FooCodec(); // encoder and decoder in one > class > InetSocketAddress local = new InetSocketAddress(port); > > acceptor = new NioDatagramAcceptor(); > acceptor.getFilterChain().addLast("executor", new > ExecutorFilter(maxThreads)); > acceptor.getFilterChain().addLast("codec", new > ProtocolCodecFilter(codec, codec)); > acceptor.setHandler(handler); > acceptor.bind(local); > > At first it seemed that each incoming UDP package, due to its stateless > nature, > creates a different Mina "session" and each Mina "session" runs in its own > thread so that the default ExecutorFilter implementation > OrderedThreadPoolExecutor is fine as I certainly don't want the session > closed > if there is still a response before it in the queue. > > Now under a bit of load, one session was a bit slower and hanging for 1,5s > and > it suddenly happened that multiple UDP packets were put into the same > Mina "session" which lead to the following log messages: > > 2013-09-24 10:56:02,910 DEBUG > org.apache.mina.filter.executor.OrderedThreadPoolExecutor : > Adding event MESSAGE_RECEIVED to session 17529 > Queue : [MESSAGE_RECEIVED, , MESSAGE_RECEIVED, , MESSAGE_RECEIVED ... ] > (OrderedThreadPoolExecutor.java:431) > > This now completely destroys the asynchronous behaviour as all packeges > had to wait > for the first one in the queue even if there were several executor threads > idling > around! > > How should I fix this problem? Using an "UnorderedThreadPoolExecutor? > Or setting acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, > 0); > Or by somehow else force the creation of a Mina "session" for each UDP > packet? > > Best Regards > > -christian- > > > P.S.: http://mina.apache.org/mina-project/documentation.html contains a > links to a "UDP Tutorial" which sadly refers to a page that does > only have APR and Serial tutorials. >
Multithreaded UDP server vs. OrderedThreadPoolExecutor
Hello I've written a server for a proprietary UDP protocol that needs to answer with exactly one packet for every incoming packet. All packets are independent from each other so that I like to have each one handled asynchronously by a different thread from a pool with a certain maximum size. So far I used this: FooCodec codec = new FooCodec(); // encoder and decoder in one class InetSocketAddress local = new InetSocketAddress(port); acceptor = new NioDatagramAcceptor(); acceptor.getFilterChain().addLast("executor", new ExecutorFilter(maxThreads)); acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(codec, codec)); acceptor.setHandler(handler); acceptor.bind(local); At first it seemed that each incoming UDP package, due to its stateless nature, creates a different Mina "session" and each Mina "session" runs in its own thread so that the default ExecutorFilter implementation OrderedThreadPoolExecutor is fine as I certainly don't want the session closed if there is still a response before it in the queue. Now under a bit of load, one session was a bit slower and hanging for 1,5s and it suddenly happened that multiple UDP packets were put into the same Mina "session" which lead to the following log messages: 2013-09-24 10:56:02,910 DEBUG org.apache.mina.filter.executor.OrderedThreadPoolExecutor : Adding event MESSAGE_RECEIVED to session 17529 Queue : [MESSAGE_RECEIVED, , MESSAGE_RECEIVED, , MESSAGE_RECEIVED ... ] (OrderedThreadPoolExecutor.java:431) This now completely destroys the asynchronous behaviour as all packeges had to wait for the first one in the queue even if there were several executor threads idling around! How should I fix this problem? Using an "UnorderedThreadPoolExecutor? Or setting acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 0); Or by somehow else force the creation of a Mina "session" for each UDP packet? Best Regards -christian- P.S.: http://mina.apache.org/mina-project/documentation.html contains a links to a "UDP Tutorial" which sadly refers to a page that does only have APR and Serial tutorials.