mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Emmanuel Lecharny (JIRA)" <j...@apache.org>
Subject [jira] Updated: (DIRMINA-682) We need a better documentation for the ExecutorFilter [was :Writing more than one message will block until the MessageReceived as been fully proceced]
Date Fri, 10 Dec 2010 18:47:08 GMT

     [ https://issues.apache.org/jira/browse/DIRMINA-682?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Emmanuel Lecharny updated DIRMINA-682:
--------------------------------------

    Fix Version/s:     (was: 2.0.2)
                   2.0.3

> We need a better documentation for the ExecutorFilter [was :Writing more than one message
will block until the MessageReceived as been fully proceced]
> ------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: DIRMINA-682
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-682
>             Project: MINA
>          Issue Type: Improvement
>    Affects Versions: 2.0.0-M4
>            Reporter: Emmanuel Lecharny
>            Priority: Critical
>             Fix For: 2.0.3
>
>
> When a message generates mor ethan one response, then the written responses will be sent
to the client only when the initial message has been totally processed.
> Suppose that we receive one message M, it will be handled by a IoProcessor in the process()
method, go through the chain to the IoHandler.MessageReceive() method. Now, if one want to
write more than one response (session.write( R )), then those responses will be enqueued until
we are back to the process() method.
> The issue is due to the fact that the write is done using the IoProcessor associated
to the current session, leading to a problem : we can't ask the IoProcessor instance to unqueue
the written message until it is done with the current processing( it's running in one single
thread).
> The consequences are painfull :
> - if one tries to write two responses, waiting for the first responses to be written,
this will end with a DeadLock, as we are waiting on the processor we are holding
> - if we don't care about waiting for the write to be done, then all the responses will
be enqueued and stored in memory, until the IoProcessor exit from the read processing and
start processing the writes, leading to OOM Exception
> One solution would be to have to sets of IoProcessors, one for the read, and one for
the writes. Or to pick a random Processor to process the writes, as soon as the processor
is not the same as the one processing the reads.
> Here is a sample exhibiting the problem. Just launch it, and use 'telnet localhost 8080'
in a console, type something, it should write twice the typed message, but it just generates
an exception - see further - and write back the message once. Removing the wait will work,
but the messages will be sent only when the read has been processed in the AbstractPollingIoProcessor.process(T
session) method :
>     /**
>      * Deal with session ready for the read or write operations, or both.
>      */
>     private void process(T session) {
>         // Process Reads
>         if (isReadable(session) && !session.isReadSuspended()) {
>             read(session);
>         }
>         // Process writes
>         if (isWritable(session) && !session.isWriteSuspended()) {
>             scheduleFlush(session);
>         }
>     }
> The sample code :
> package org.apache.mina.real.life;
> import java.net.InetSocketAddress;
> import org.apache.mina.core.buffer.IoBuffer;
> import org.apache.mina.core.future.WriteFuture;
> import org.apache.mina.core.service.IoHandlerAdapter;
> import org.apache.mina.core.session.IoSession;
> import org.apache.mina.filter.logging.LoggingFilter;
> import org.apache.mina.transport.socket.SocketAcceptor;
> import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
> /**
>  * (<b>Entry point</b>) Echo server
>  *
>  * @author The Apache MINA Project (dev@mina.apache.org)
>  */
> public class Main {
>     private static class EchoProtocolHandler extends IoHandlerAdapter {
>         public void messageReceived(IoSession session, Object message)
>                 throws Exception {
>             System.out.println(new String(((IoBuffer)message).array()));
>             // Write the received data back to remote peer
>             WriteFuture wf = session.write(((IoBuffer) message).duplicate());
>             
>             // Here, we will get a Deadlock detection
>             wf.awaitUninterruptibly();
>             
>             // Do a second write
>             session.write(((IoBuffer) message).duplicate());
>         }
>     }    
>     /** Choose your favorite port number. */
>     private static final int PORT = 8080;
>     public static void main(String[] args) throws Exception {
>         SocketAcceptor acceptor = new NioSocketAcceptor();
>         
>         // Add a logging filter
>         acceptor.getFilterChain().addLast( "Logger", new LoggingFilter() );
>         
>         // Bind
>         acceptor.setHandler(new EchoProtocolHandler());
>         acceptor.bind(new InetSocketAddress(PORT));
>         System.out.println("Listening on port " + PORT);
>     }
> }
> The exception :
> Listening on port 8080
> [20:08:17] INFO [org.apache.mina.filter.logging.LoggingFilter] - CREATED
> [20:08:17] INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENED
> [20:08:19] INFO [org.apache.mina.filter.logging.LoggingFilter] - RECEIVED: HeapBuffer[pos=0
lim=6 cap=2048: 74 65 73 74 0D 0A]
> test
> [20:08:30] WARN [org.apache.mina.filter.logging.LoggingFilter] - EXCEPTION :
> java.lang.IllegalStateException: DEAD LOCK: IoFuture.await() was invoked from an I/O
processor thread.  Please use IoFutureListener or configure a proper thread model alternatively.
> 	at org.apache.mina.core.future.DefaultIoFuture.checkDeadLock(DefaultIoFuture.java:235)
> 	at org.apache.mina.core.future.DefaultIoFuture.await0(DefaultIoFuture.java:203)
> 	at org.apache.mina.core.future.DefaultIoFuture.awaitUninterruptibly(DefaultIoFuture.java:131)
> 	at org.apache.mina.core.future.DefaultWriteFuture.awaitUninterruptibly(DefaultWriteFuture.java:114)
> 	at org.apache.mina.real.life.Main$EchoProtocolHandler.messageReceived(Main.java:45)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:722)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:48)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:802)
> 	at org.apache.mina.filter.logging.LoggingFilter.messageReceived(LoggingFilter.java:178)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:48)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:802)
> 	at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:120)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:426)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:604)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:564)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:553)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:57)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:892)
> 	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:65)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> 	at java.lang.Thread.run(Thread.java:619)
> [20:08:30] WARN [org.apache.mina.real.life.Main$EchoProtocolHandler] - EXCEPTION, please
implement org.apache.mina.real.life.Main$EchoProtocolHandler.exceptionCaught() for proper
handling:
> java.lang.IllegalStateException: DEAD LOCK: IoFuture.await() was invoked from an I/O
processor thread.  Please use IoFutureListener or configure a proper thread model alternatively.
> 	at org.apache.mina.core.future.DefaultIoFuture.checkDeadLock(DefaultIoFuture.java:235)
> 	at org.apache.mina.core.future.DefaultIoFuture.await0(DefaultIoFuture.java:203)
> 	at org.apache.mina.core.future.DefaultIoFuture.awaitUninterruptibly(DefaultIoFuture.java:131)
> 	at org.apache.mina.core.future.DefaultWriteFuture.awaitUninterruptibly(DefaultWriteFuture.java:114)
> 	at org.apache.mina.real.life.Main$EchoProtocolHandler.messageReceived(Main.java:45)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:722)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:48)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:802)
> 	at org.apache.mina.filter.logging.LoggingFilter.messageReceived(LoggingFilter.java:178)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:48)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:802)
> 	at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:120)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
> 	at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:426)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:604)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:564)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:553)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:57)
> 	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:892)
> 	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:65)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> 	at java.lang.Thread.run(Thread.java:619)
> [20:08:30] INFO [org.apache.mina.filter.logging.LoggingFilter] - SENT: HeapBuffer[pos=0
lim=6 cap=2048: 74 65 73 74 0D 0A]

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message