On 02/10/13 11:34, Norman Walsh wrote:
Norman Walsh <[email protected]> writes:
I'll keep hacking at it.

Here you go. JenaStreamTest reads /tmp/badchar.ttl and hangs. It doesn't
*always* hang but it almost always does.

Here's what I think happens. In PipedRDFIterator we find this loop:

         while (true)
         {
             try
             {
                 slot = queue.poll(ITERATOR_POLL_TIMEOUT, 
ITERATOR_POLL_TIMEUNIT) ;
             }
             catch (InterruptedException e)
             {
                 throw new CancellationException() ;
             }

             if (null != slot)
                 break ;

             // If the producer thread died and did not call finish() then declare this 
pipe to be "broken"
             // Since check is after the break, we will drain as much as 
possible out of the queue before throwing this exception
             if (writeSide != null && !writeSide.isAlive() && !closedByWriter)
             {
                 closedByReader = true ;
                 throw new RiotException("Write end dead") ;
             }
         }

But the writing thread dies before ever calling PipedRDFIterator.receive(), so
writeSide is null, the queue is empty, and we're stuck.

>
> I'll be pleased as can be if this is just a case of me doing
> something wrong.

The exact reason it fails in RiotReader.createParser is because at that point, the code starts reading bytes. That might seem odd at create time but it's going to handle a possible BOM at that point. It reads in large chunks for efficiency.

If it weren't for the BOM, it could delay reading (and the later peeking iterator for tokens would also need to delay filling internal datastructure which it doesn't).

Somehow, the end of stream object needs sending if RiotReader.createParser fails. Now sure how though. Dummy parser that does nothing?


Possible basis for a workaround:

@Override
public void run() {
    LangRIOT parser ;
    try {
        parser = RiotReader.createParser(in, lang, fsname,
                                         rdfInputStream);
    }
    catch (Exception ex) {
        byte[] b = new byte[0] ;
        InputStream in2 = new ByteArrayInputStream(b) ;
        parser = RiotReader.createParser(in2, lang, fsname,
                                         rdfInputStream);
    }

    parser.parse();
}

which silently discards the input.

Add error handling to taste.

        Andy




                                         Be seeing you,
                                           norm


Reply via email to