mirror of https://github.com/apache/lucene.git
LUCENE-9408: Ensure OneMerge#mergeFinished is only called once (#1590)
in the case of an exception it's possible that some OneMerge instances will be closed multiple times. This commit ensures that mergeFinished is really just called once instead of multiple times.
This commit is contained in:
parent
6a455866b0
commit
f47de19c4e
|
@ -29,6 +29,7 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
@ -4286,6 +4287,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable,
|
||||||
|
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
private synchronized void closeMergeReaders(MergePolicy.OneMerge merge, boolean suppressExceptions) throws IOException {
|
private synchronized void closeMergeReaders(MergePolicy.OneMerge merge, boolean suppressExceptions) throws IOException {
|
||||||
|
if (merge.hasFinished() == false) {
|
||||||
final boolean drop = suppressExceptions == false;
|
final boolean drop = suppressExceptions == false;
|
||||||
try (Closeable finalizer = () -> merge.mergeFinished(suppressExceptions == false)) {
|
try (Closeable finalizer = () -> merge.mergeFinished(suppressExceptions == false)) {
|
||||||
IOUtils.applyToAll(merge.readers, sr -> {
|
IOUtils.applyToAll(merge.readers, sr -> {
|
||||||
|
@ -4306,6 +4308,10 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable,
|
||||||
} finally {
|
} finally {
|
||||||
Collections.fill(merge.readers, null);
|
Collections.fill(merge.readers, null);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
assert merge.readers.stream().filter(Objects::nonNull).count() == 0 : "we are done but still have readers: " + merge.readers;
|
||||||
|
assert suppressExceptions : "can't be done and not suppressing exceptions";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void countSoftDeletes(CodecReader reader, Bits wrappedLiveDocs, Bits hardLiveDocs, Counter softDeleteCounter,
|
private void countSoftDeletes(CodecReader reader, Bits wrappedLiveDocs, Bits hardLiveDocs, Counter softDeleteCounter,
|
||||||
|
|
|
@ -256,11 +256,9 @@ public abstract class MergePolicy {
|
||||||
/** Called by {@link IndexWriter} after the merge is done and all readers have been closed.
|
/** Called by {@link IndexWriter} after the merge is done and all readers have been closed.
|
||||||
* @param success true iff the merge finished successfully ie. was committed */
|
* @param success true iff the merge finished successfully ie. was committed */
|
||||||
public void mergeFinished(boolean success) throws IOException {
|
public void mergeFinished(boolean success) throws IOException {
|
||||||
mergeCompleted.complete(success);
|
if (mergeCompleted.complete(success) == false) {
|
||||||
// https://issues.apache.org/jira/browse/LUCENE-9408
|
throw new IllegalStateException("merge has already finished");
|
||||||
// if (mergeCompleted.complete(success) == false) {
|
}
|
||||||
// throw new IllegalStateException("merge has already finished");
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wrap the reader in order to add/remove information to the merged segment. */
|
/** Wrap the reader in order to add/remove information to the merged segment. */
|
||||||
|
@ -390,7 +388,7 @@ public abstract class MergePolicy {
|
||||||
* Returns true if the merge has finished or false if it's still running or
|
* Returns true if the merge has finished or false if it's still running or
|
||||||
* has not been started. This method will not block.
|
* has not been started. This method will not block.
|
||||||
*/
|
*/
|
||||||
boolean isDone() {
|
boolean hasFinished() {
|
||||||
return mergeCompleted.isDone();
|
return mergeCompleted.isDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,6 @@ public class TestMergePolicy extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-9408")
|
|
||||||
public void testFinishTwice() throws IOException {
|
public void testFinishTwice() throws IOException {
|
||||||
try (Directory dir = newDirectory()) {
|
try (Directory dir = newDirectory()) {
|
||||||
MergePolicy.MergeSpecification spec = createRandomMergeSpecification(dir, 1);
|
MergePolicy.MergeSpecification spec = createRandomMergeSpecification(dir, 1);
|
||||||
|
|
Loading…
Reference in New Issue