Hi,
I would like to report a potential bug in Camel's use of jsch/java.io, and
find a potential workaround.  

Apologies in advance for abusing terms -- I am only a Camel user, I am not
intimately familiar with its implementation.

We have an indefinite polling route that does a directory listing on a
third-party's sftp server, and subsequently downloads "new" files and does
things with them.

A couple times per year, this route halts apparent operation with no error
logged, and no impact to other jvm activities.  The impact of this behavior
is dire to us -- there is no error reported, yet Camel is not doing
anything.

Looking at a thread dump, the "sftp" camel thread is stuck in an apparent
infinite loop in java.io.PipedInputStream.read().  Ignoring the deeply weird
use of thread safety in this class for a moment, it appears that this can
happen if Camel moves its processor instance of this sftp route to a
different thread while it is processing.

public synchronized int read() throws IOException {
    if (!connected) {
        throw new IOException("Pipe not connected");
    } else if (closedByReader) {
        throw new IOException("Pipe closed");
    } else if (writeSide != null && !writeSide.isAlive()
        && !closedByWriter && (in < 0)) {
        throw new IOException("Write end dead");
    }

    readSide = Thread.currentThread();
    int trials = 2;
    while (in < 0) {
        if (closedByWriter) {
            /* closed by writer, return EOF */
            return -1;
        }
        if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0))
{  // <----- If writeSide is null, infinite loop?
            throw new IOException("Pipe broken");
        }
        /* might be a writer waiting */
        notifyAll();
        try {
            wait(100);  // <----  MY THREAD SPENDS 100% TIME HERE
        } catch (InterruptedException ex) {
            throw new java.io.InterruptedIOException();
        }
    }
    int ret = buffer[out++] & 0xFF;
    if (out >= buffer.length) {
        out = 0;
    }
    if (in == out) {
        /* now empty */
        in = -1;
    }
    return ret;
}


Might that be the case?  If it is, what is the recommended way of tearing
down a route and then rebuilding it?  Most of the "shutdown" docs are aimed
at shutting down an entire container, which we most certainly do not want to
do.

And should camel do this by default on routes that use
jsch/java.io.PipedInputStream as a transport implementation?  It seems like
the resources required to spin up a new thread would be dwarfed by creating
a new ssh connection.

If that is not the case, is there any other known issue about polling sftp
routes?  I've googled around and I have not found anything, yet we have seen
this half a dozen times over the last few months.

Any advice is appreciated!

Thanks!
-neil



--
View this message in context: 
http://camel.465427.n5.nabble.com/Camel-s-use-of-jsch-java-io-tp5740623.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply via email to