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