[ 
https://issues.apache.org/jira/browse/LUCENE-7248?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15532140#comment-15532140
 ] 

Otmar Caduff commented on LUCENE-7248:
--------------------------------------

We too stumbled over this. In our setup, Lucene is run within an servlet 
container. So queries are executed by threads working down servlet calls. Now 
when a connection is closed prematurely by the client, the executing thread 
seems to be interrupted, leading to this problem.

Using RAFDirectory did not solve the problem.
RAFDirectory seems to use RandomAccessFile for reading only, writing is 
delegated to FSDirectory, since RAFDirectory inherits from FSDirectory. Inside 
the RAFDirectory implementation, I cannot see anything indicating that writing 
would be done with RandomAccessFile as well (maybe this should be pointed out 
in the javadoc?).
In our case, index readers/searchers used to call 
{{SearcherManager.maybeRefresh()}}, which occasionally involves a flush to the 
index files:
{noformat}
Caused by: java.nio.channels.ClosedByInterruptException: null
        at 
java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
        at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:216)
        at java.nio.channels.Channels.writeFullyImpl(Channels.java:78)
        at java.nio.channels.Channels.writeFully(Channels.java:101)
        at java.nio.channels.Channels.access$000(Channels.java:61)
        at java.nio.channels.Channels$1.write(Channels.java:174)
        at 
org.apache.lucene.store.FSDirectory$FSIndexOutput$1.write(FSDirectory.java:278)
        at java.util.zip.CheckedOutputStream.write(CheckedOutputStream.java:73)
        at 
java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at 
org.apache.lucene.store.OutputStreamIndexOutput.getChecksum(OutputStreamIndexOutput.java:80)
        at org.apache.lucene.codecs.CodecUtil.writeCRC(CodecUtil.java:473)
        at org.apache.lucene.codecs.CodecUtil.writeFooter(CodecUtil.java:309)
        at 
org.apache.lucene.codecs.compressing.CompressingStoredFieldsIndexWriter.finish(CompressingStoredFieldsIndexWriter.java:205)
        at 
org.apache.lucene.codecs.compressing.CompressingStoredFieldsWriter.finish(CompressingStoredFieldsWriter.java:467)
        at 
org.apache.lucene.index.DefaultIndexingChain.flush(DefaultIndexingChain.java:108)
        at 
org.apache.lucene.index.DocumentsWriterPerThread.flush(DocumentsWriterPerThread.java:422)
        at 
org.apache.lucene.index.DocumentsWriter.doFlush(DocumentsWriter.java:503)
        at 
org.apache.lucene.index.DocumentsWriter.flushAllThreads(DocumentsWriter.java:615)
        at org.apache.lucene.index.IndexWriter.getReader(IndexWriter.java:424)
        at 
org.apache.lucene.index.StandardDirectoryReader.doOpenFromWriter(StandardDirectoryReader.java:286)
        at 
org.apache.lucene.index.StandardDirectoryReader.doOpenIfChanged(StandardDirectoryReader.java:261)
        at 
org.apache.lucene.index.StandardDirectoryReader.doOpenIfChanged(StandardDirectoryReader.java:251)
        at 
org.apache.lucene.index.DirectoryReader.openIfChanged(DirectoryReader.java:137)
        at 
org.apache.lucene.search.SearcherManager.refreshIfNeeded(SearcherManager.java:154)
        at 
org.apache.lucene.search.SearcherManager.refreshIfNeeded(SearcherManager.java:58)
        at 
org.apache.lucene.search.ReferenceManager.doMaybeRefresh(ReferenceManager.java:176)
        at 
org.apache.lucene.search.ReferenceManager.maybeRefresh(ReferenceManager.java:225)
{noformat}
I changed our code so that {{SearcherManager.maybeRefresh()}} is called by the 
indexing thread, which is not being interrupted, since it is not processing 
servlet calls.
Correct me if I'm wrong: Since using IndexSearcher alone does not involve any 
write operations, I am safe against ClosedChannelException.
In the long run, I'll try to find a way to prevent using RAFDirectory, i.e. 
prevent the container interrupting querying threads.

> Interrupting IndexWriter causing unhandled ClosedChannelException
> -----------------------------------------------------------------
>
>                 Key: LUCENE-7248
>                 URL: https://issues.apache.org/jira/browse/LUCENE-7248
>             Project: Lucene - Core
>          Issue Type: Bug
>          Components: core/store
>    Affects Versions: 5.3
>            Reporter: Alexandre Philbert
>              Labels: exception, interrupt, lock, nio, release
>
> When interrupting the IndexWriter, sometimes an InterruptedException is 
> correctly handled but other times it isn't. When unhandled, the IndexWriter 
> 'closes' and any other operation throws AlreadyClosedException. Here is a 
> stack trace: 
> java.nio.channels.ClosedChannelException
>     at sun.nio.ch.FileLockImpl.release(FileLockImpl.java:58)
>     at java.nio.channels.FileLock.close(FileLock.java:309)
>     at 
> org.apache.lucene.store.NativeFSLockFactory$NativeFSLock.close(NativeFSLockFactory.java:194)
>     at org.apache.lucene.util.IOUtils.close(IOUtils.java:97)
>     at org.apache.lucene.util.IOUtils.close(IOUtils.java:84)
>     at 
> org.apache.lucene.index.IndexWriter.rollbackInternal(IndexWriter.java:2103)
>     at org.apache.lucene.index.IndexWriter.tragicEvent(IndexWriter.java:4574)
>     at 
> org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1487)
>     at 
> com.google.gerrit.lucene.AutoCommitWriter.updateDocument(AutoCommitWriter.java:100)
>     at 
> org.apache.lucene.index.TrackingIndexWriter.updateDocument(TrackingIndexWriter.java:55)
>     at com.google.gerrit.lucene.SubIndex.replace(SubIndex.java:183)
>     at 
> com.google.gerrit.lucene.LuceneChangeIndex.replace(LuceneChangeIndex.java:326)
>     at 
> com.google.gerrit.server.index.ChangeIndexer$IndexTask.call(ChangeIndexer.java:243)
>     at 
> com.google.gerrit.server.index.ChangeIndexer$IndexTask.call(ChangeIndexer.java:1)
>     at 
> com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:108)
>     at 
> com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:41)
>     at 
> com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:77)
>     at 
> com.google.common.util.concurrent.MoreExecutors$DirectExecutorService.execute(MoreExecutors.java:310)
>     at 
> java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:132)
>     at 
> com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:61)
>     at 
> com.google.gerrit.server.index.ChangeIndexer.submit(ChangeIndexer.java:200)
>     at 
> com.google.gerrit.server.index.ChangeIndexer.indexAsync(ChangeIndexer.java:133)
>     at 
> com.google.gerrit.server.change.PostReviewers.addReviewers(PostReviewers.java:246)
>     at 
> com.google.gerrit.server.change.PostReviewers.putAccount(PostReviewers.java:156)
>     at 
> com.google.gerrit.server.change.PostReviewers.apply(PostReviewers.java:138)
>     at 
> com.google.gerrit.sshd.commands.SetReviewersCommand.modifyOne(SetReviewersCommand.java:158)
>     at 
> com.google.gerrit.sshd.commands.SetReviewersCommand.run(SetReviewersCommand.java:112)
>     at com.google.gerrit.sshd.SshCommand$1.run(SshCommand.java:48)
>     at com.google.gerrit.sshd.BaseCommand$TaskThunk.run(BaseCommand.java:442)
>     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
>     at java.util.concurrent.FutureTask.run(FutureTask.java:262)
>     at 
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
>     at 
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
>     at com.google.gerrit.server.git.WorkQueue$Task.run(WorkQueue.java:377)
>     at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
>     at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
>     at java.lang.Thread.run(Thread.java:745)
> [...]
> org.apache.lucene.store.AlreadyClosedException: this IndexWriter is closed
>       at org.apache.lucene.index.IndexWriter.ensureOpen(IndexWriter.java:719)
>       at org.apache.lucene.index.IndexWriter.ensureOpen(IndexWriter.java:733)
>       at 
> org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1471)
>       at 
> com.google.gerrit.lucene.AutoCommitWriter.updateDocument(AutoCommitWriter.java:100)
>       at 
> org.apache.lucene.index.TrackingIndexWriter.updateDocument(TrackingIndexWriter.java:55)
>       at com.google.gerrit.lucene.SubIndex.replace(SubIndex.java:183)
>       at 
> com.google.gerrit.lucene.LuceneChangeIndex.replace(LuceneChangeIndex.java:326)
>       at 
> com.google.gerrit.server.index.ChangeIndexer$IndexTask.call(ChangeIndexer.java:243)
>       at 
> com.google.gerrit.server.index.ChangeIndexer$IndexTask.call(ChangeIndexer.java:1)
>       at 
> com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:108)
>       at 
> com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:41)
>       at 
> com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:77)
>       at 
> com.google.common.util.concurrent.MoreExecutors$DirectExecutorService.execute(MoreExecutors.java:310)
>       at 
> java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:132)
>       at 
> com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:61)
>       at 
> com.google.gerrit.server.index.ChangeIndexer.submit(ChangeIndexer.java:200)
>       at 
> com.google.gerrit.server.index.ChangeIndexer.indexAsync(ChangeIndexer.java:133)
>       at 
> com.google.gerrit.server.change.PostReviewers.addReviewers(PostReviewers.java:246)
>       at 
> com.google.gerrit.server.change.PostReviewers.putAccount(PostReviewers.java:156)
>       at 
> com.google.gerrit.server.change.PostReviewers.apply(PostReviewers.java:138)
>       at 
> com.google.gerrit.sshd.commands.SetReviewersCommand.modifyOne(SetReviewersCommand.java:158)
>       at 
> com.google.gerrit.sshd.commands.SetReviewersCommand.run(SetReviewersCommand.java:112)
>       at com.google.gerrit.sshd.SshCommand$1.run(SshCommand.java:48)
>       at 
> com.google.gerrit.sshd.BaseCommand$TaskThunk.run(BaseCommand.java:442)
>       at 
> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
>       at java.util.concurrent.FutureTask.run(FutureTask.java:262)
>       at 
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
>       at 
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
>       at com.google.gerrit.server.git.WorkQueue$Task.run(WorkQueue.java:377)
>       at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
>       at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
>       at java.lang.Thread.run(Thread.java:745)
> Caused by: java.nio.channels.ClosedByInterruptException
>       at 
> java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
>       at sun.nio.ch.FileChannelImpl.size(FileChannelImpl.java:312)
>       at 
> org.apache.lucene.store.NativeFSLockFactory$NativeFSLock.ensureValid(NativeFSLockFactory.java:170)
>       at 
> org.apache.lucene.store.LockValidatingDirectoryWrapper.createOutput(LockValidatingDirectoryWrapper.java:43)
>       at 
> org.apache.lucene.store.TrackingDirectoryWrapper.createOutput(TrackingDirectoryWrapper.java:43)
>       at 
> org.apache.lucene.codecs.compressing.CompressingStoredFieldsWriter.<init>(CompressingStoredFieldsWriter.java:110)
>       at 
> org.apache.lucene.codecs.compressing.CompressingStoredFieldsFormat.fieldsWriter(CompressingStoredFieldsFormat.java:128)
>       at 
> org.apache.lucene.codecs.lucene50.Lucene50StoredFieldsFormat.fieldsWriter(Lucene50StoredFieldsFormat.java:183)
>       at 
> org.apache.lucene.index.DefaultIndexingChain.initStoredFieldsWriter(DefaultIndexingChain.java:81)
>       at 
> org.apache.lucene.index.DefaultIndexingChain.startStoredFields(DefaultIndexingChain.java:258)
>       at 
> org.apache.lucene.index.DefaultIndexingChain.processDocument(DefaultIndexingChain.java:295)
>       at 
> org.apache.lucene.index.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:234)
>       at 
> org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:450)
>       at 
> org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1475)
>       ... 29 more



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to