[
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]