DIRMINA-129 created to cover this issue.


From: Irving, Dave [mailto:[EMAIL PROTECTED]
Sent: 24 November 2005 17:55
To: Apache Directory Developers List
Subject: RE: [MINA] Error on StreamIOHandler

I can confirm that I've now reproduced this problem. Changing the ThreadPoolFilter keep-alive time changes the amount of time required before the exception is obvserved - so I think we got to the root cause (PipedInputStream doesn't like producer threads dying).
 
Possible solutions which spring to mind:
 
1) Mina could use its own "MinaPipedInput/OutputStream" or something.
2) A ThreadPoolFilter Worker thread could somehow know that it was logically still required even though it hadn't been active for a while (maybe a session attribute?). StreamIoHandler would then set this attribute on a write or something like that (and remove it onIdle / close whatever). This is quite a bit more hacky than (1).
 
Dave


From: Jose Alberto Fernandez [mailto:[EMAIL PROTECTED]
Sent: 24 November 2005 16:53
To: Apache Directory Developers List
Subject: RE: [MINA] Error on StreamIOHandler

Thanks Dave, now I understand the issue.

Will see if you guys come with a smart solution before mocking with the thread parameters since we use several protocols and they all share the same threadfilter in the IoAcceptor.

 

Jose Alberto

 


From: Irving, Dave [mailto:[EMAIL PROTECTED]
Sent: 24 November 2005 16:05
To: Apache Directory Developers List
Subject: RE: [MINA] Error on StreamIOHandler

 

Expanding a bit on this:

 

ThreadPoolFilter has a default keep alive time of one minute.

If no work comes in to the filter in this time (e.g because you haven't typed anything for a while), a worker thread could shut down.

 

So, in your example, the following could happen:

 

1) You write some data over telnet

2) A processor thread writes the data to the StreamIoHandlers PipedOutputStream

3) Your PipedInputStream reads the data. At this point, the processor thread is marked as the last writer (PipedInputStrea#writeSide).

4) You dont send any data for a while (so you are currently blocked in final String command = in.readLine(); in your code).

5) The processor thread idles out (default keep-alive time is one minute)

6) The PipedInputStream detects that the last writer thread is no longer alive and throws a "Pipe Broken" IOException

7) Your code writes this back to the client (in your catch block)

8) Your code closes the connection (your finally block)

 

I think thats probably whats happening.

 

To test my theory, try increasing the idle time out of the ThreadPoolFilter - you shouldn't get the exception until this time has elapsed (or decrease it, and observe the failure quicker).

 

So maybe we need to either use a custom piped stream in StreamIOHandler , or be careful with processor thread keep alives when using VM pipe?

 

Dave

Dave

 

 

 

 

 


From: Jose Alberto Fernandez [mailto:[EMAIL PROTECTED]
Sent: 24 November 2005 15:51
To: Apache Directory Developers List
Subject: RE: [MINA] Error on StreamIOHandler

Thanks, not sure if this is my case. As a matter of fact, the stack trace that I printed comes as part of the Telnet output just before the connection is closed.

 

This are some abstracts of the code loop of my worker thread:

 

    protected void processStreamIo(IoSession i_ioSession, InputStream i_inputStream, OutputStream i_outputStream) {

        try {

            EXECUTOR_SERVICE.execute(new Worker(i_inputStream, i_outputStream));

        } catch (IOException e) {

            e.printStackTrace();

            i_ioSession.close();

        }

    }

 

        public Worker(final InputStream i_in, final OutputStream i_out) throws IOException {

            in = new BufferedReader(new InputStreamReader( i_in ) );

            out = new PrintWriter(new BufferedWriter( new OutputStreamWriter( i_out ) ), true);

        }

 

        public void run() {

            try {

                while (true) {

                    final String command = in.readLine();

                    if (processCommand(command.trim())) {

                        break;

                    }

                }

            } catch (IOException e) {

                e.printStackTrace(out);

            } finally {

                out.close();

            }

        }

 

As you can see the stack trace is send to the telnet client before closing the connection.

 


From: Irving, Dave [mailto:[EMAIL PROTECTED]
Sent: 24 November 2005 15:26
To: Apache Directory Developers List
Subject: RE: [MINA] Error on StreamIOHandler

 

This is just a guess off the top of my head (so apologies if its wildly inaccurate), but I wonder whether it has anything to do with processor threads being shut down if they dont do any work?

When an attempt is made to read from a PipedInputStream, a check is made every second to see whether the last thread to write to the associated PipedOutputStream is still alive.

 

From PipedInputStream:

 

int trials = 2;
 while (in < 0) {
     if (closedByWriter) {
  /* closed by writer, return EOF */
  return -1;
     }
     if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
  throw new IOException("Pipe broken");
     }
            /* might be a writer waiting */
     notifyAll();
     try {
         wait(1000);
     } catch (InterruptedException ex) {
  throw new java.io.InterruptedIOException();
     }
  }

 

So, if mina shuts down the thread which caused the last write after inactivity (which I think it might do), this could be the cause.


Dave

 


From: Jose Alberto Fernandez [mailto:[EMAIL PROTECTED]
Sent: 24 November 2005 15:11
To: Apache Directory Developers List
Subject: [MINA] Error on StreamIOHandler

Hi, we are getting the following stack trace when one is not constantly typing on a telnet session connected using StreamIOHandler:

 

java.io.IOException: Pipe broken

        at java.io.PipedInputStream.read(PipedInputStream.java:255)

        at org.apache.mina.io.handler.StreamIoHandler$PipedInputStream.read(StreamIoHandler.java:223)

        at java.io.PipedInputStream.read(PipedInputStream.java:305)

        at org.apache.mina.io.handler.StreamIoHandler$PipedInputStream.read(StreamIoHandler.java:229)

        at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411)

        at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453)

        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183)

        at java.io.InputStreamReader.read(InputStreamReader.java:167)

        at java.io.BufferedReader.fill(BufferedReader.java:136)

        at java.io.BufferedReader.readLine(BufferedReader.java:299)

        at java.io.BufferedReader.readLine(BufferedReader.java:362)

        at com.cellectivity.poker.clienthandler.telnet.PokerTelnetHandler$Worker.run(PokerTelnetHandler.java:340)

        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)

        at java.lang.Thread.run(Thread.java:595)

 

This is MINA 0.8.1. We have only one connection and this occurs every time we do not use the telnet session for a little while,

less than a minute. Has anyone seen this error before? Any way to solve it?

 

Jose Alberto

 

 

This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.

Reply via email to