Skip to content

Commit 74c20f1

Browse files
Assert That AbstractRefCounted#decRef Does not Throw on Closing (#70373)
We should not allow exceptions in the internal close I think. If the exceptions thrown here are fatal then they should just be errors instead as well. If they are not and need handling then the handling should happen in the `closeInternal` call. Otherwise, all callers of `decRef` must be aware of necessary exception handling which would make reasoning about the behavior of exceptions in `#closeInternal` extremely complicated.
1 parent 6ad7695 commit 74c20f1

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

libs/core/src/main/java/org/elasticsearch/common/util/concurrent/AbstractRefCounted.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ public final boolean decRef() {
5151
int i = refCount.decrementAndGet();
5252
assert i >= 0;
5353
if (i == 0) {
54-
closeInternal();
54+
try {
55+
closeInternal();
56+
} catch (Exception e) {
57+
assert false : e;
58+
throw e;
59+
}
5560
return true;
5661
}
5762
return false;
@@ -81,5 +86,9 @@ public String getName() {
8186
return name;
8287
}
8388

89+
/**
90+
* Method that is invoked once the reference count reaches zero.
91+
* Implementations of this method must handle all exceptions and may not throw any exceptions.
92+
*/
8493
protected abstract void closeInternal();
8594
}

server/src/main/java/org/elasticsearch/index/store/Store.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
import java.io.IOException;
7777
import java.io.InputStream;
7878
import java.io.PrintStream;
79-
import java.io.UncheckedIOException;
8079
import java.nio.file.NoSuchFileException;
8180
import java.nio.file.Path;
8281
import java.util.ArrayList;
@@ -420,7 +419,8 @@ private void closeInternal() {
420419
onClose.accept(shardLock);
421420
}
422421
} catch (IOException e) {
423-
throw new UncheckedIOException(e);
422+
assert false : e;
423+
logger.warn(() -> new ParameterizedMessage("exception on closing store for [{}]", shardId), e);
424424
}
425425
}
426426

server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,11 +3095,14 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
30953095
Files.walkFileTree(indexPath, corruptedVisitor);
30963096
assertThat("store has to be marked as corrupted", corruptedMarkerCount.get(), equalTo(1));
30973097

3098+
// Close the directory under the shard first because it's probably a MockDirectoryWrapper which throws exceptions when corrupt
30983099
try {
3099-
closeShards(corruptedShard);
3100-
} catch (RuntimeException e) {
3101-
// Ignored because corrupted shard can throw various exceptions on close
3100+
((FilterDirectory) corruptedShard.store().directory()).getDelegate().close();
3101+
} catch (CorruptIndexException | RuntimeException e) {
3102+
// ignored
31023103
}
3104+
3105+
closeShards(corruptedShard);
31033106
}
31043107

31053108
public void testShardDoesNotStartIfCorruptedMarkerIsPresent() throws Exception {

0 commit comments

Comments
 (0)