|
67 | 67 | import org.elasticsearch.common.util.concurrent.ThreadContext; |
68 | 68 | import org.elasticsearch.core.Assertions; |
69 | 69 | import org.elasticsearch.core.Booleans; |
| 70 | +import org.elasticsearch.core.CheckedFunction; |
70 | 71 | import org.elasticsearch.core.IOUtils; |
71 | 72 | import org.elasticsearch.core.Nullable; |
72 | 73 | import org.elasticsearch.core.Releasable; |
|
106 | 107 |
|
107 | 108 | import java.io.Closeable; |
108 | 109 | import java.io.IOException; |
109 | | -import java.io.UncheckedIOException; |
110 | 110 | import java.util.Arrays; |
111 | 111 | import java.util.Collections; |
112 | 112 | import java.util.List; |
@@ -1021,16 +1021,17 @@ private VersionValue resolveDocVersion(final Operation op, boolean loadSeqNo) th |
1021 | 1021 | VersionValue versionValue = getVersionFromMap(op.uid()); |
1022 | 1022 | if (versionValue == null) { |
1023 | 1023 | assert incrementIndexVersionLookup(); // used for asserting in tests |
1024 | | - final VersionsAndSeqNoResolver.DocIdAndVersion docIdAndVersion; |
1025 | | - try (var directoryReaderSupplier = acquireDirectoryReaderSupplier(SearcherScope.INTERNAL)) { |
1026 | | - var indexReader = directoryReaderSupplier.getDirectoryReader(); |
1027 | | - if (engineConfig.getIndexSettings().getMode() == IndexMode.TIME_SERIES) { |
1028 | | - assert engineConfig.getLeafSorter() == DataStream.TIMESERIES_LEAF_READERS_SORTER; |
1029 | | - docIdAndVersion = VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(indexReader, op.uid(), op.id(), loadSeqNo); |
1030 | | - } else { |
1031 | | - docIdAndVersion = VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(indexReader, op.uid(), loadSeqNo); |
| 1024 | + final VersionsAndSeqNoResolver.DocIdAndVersion docIdAndVersion = performActionWithDirectoryReader( |
| 1025 | + SearcherScope.INTERNAL, |
| 1026 | + directoryReader -> { |
| 1027 | + if (engineConfig.getIndexSettings().getMode() == IndexMode.TIME_SERIES) { |
| 1028 | + assert engineConfig.getLeafSorter() == DataStream.TIMESERIES_LEAF_READERS_SORTER; |
| 1029 | + return VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(directoryReader, op.uid(), op.id(), loadSeqNo); |
| 1030 | + } else { |
| 1031 | + return VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(directoryReader, op.uid(), loadSeqNo); |
| 1032 | + } |
1032 | 1033 | } |
1033 | | - } |
| 1034 | + ); |
1034 | 1035 | if (docIdAndVersion != null) { |
1035 | 1036 | versionValue = new IndexVersionValue(null, docIdAndVersion.version, docIdAndVersion.seqNo, docIdAndVersion.primaryTerm); |
1036 | 1037 | } |
@@ -3464,57 +3465,25 @@ protected long getPreCommitSegmentGeneration() { |
3464 | 3465 | return preCommitSegmentGeneration.get(); |
3465 | 3466 | } |
3466 | 3467 |
|
3467 | | - DirectoryReaderSupplier acquireDirectoryReaderSupplier(SearcherScope scope) throws EngineException { |
3468 | | - assert scope == SearcherScope.INTERNAL : "acquireDirectoryReaderSupplier(...) isn't prepared for external usage"; |
| 3468 | + <T> T performActionWithDirectoryReader(SearcherScope scope, CheckedFunction<DirectoryReader, T, IOException> action) |
| 3469 | + throws EngineException { |
| 3470 | + assert scope == SearcherScope.INTERNAL : "performActionWithDirectoryReader(...) isn't prepared for external usage"; |
3469 | 3471 | assert store.hasReferences(); |
3470 | 3472 | try { |
3471 | 3473 | ReferenceManager<ElasticsearchDirectoryReader> referenceManager = getReferenceManager(scope); |
3472 | 3474 | ElasticsearchDirectoryReader acquire = referenceManager.acquire(); |
3473 | | - return new DirectoryReaderSupplier(acquire) { |
3474 | | - |
3475 | | - @Override |
3476 | | - void doClose() { |
3477 | | - try { |
3478 | | - referenceManager.release(acquire); |
3479 | | - } catch (IOException e) { |
3480 | | - throw new UncheckedIOException("failed to close", e); |
3481 | | - } catch (AlreadyClosedException e) { |
3482 | | - // This means there's a bug somewhere: don't suppress it |
3483 | | - throw new AssertionError(e); |
3484 | | - } |
3485 | | - } |
3486 | | - }; |
| 3475 | + try { |
| 3476 | + return action.apply(acquire); |
| 3477 | + } finally { |
| 3478 | + referenceManager.release(acquire); |
| 3479 | + } |
3487 | 3480 | } catch (AlreadyClosedException ex) { |
3488 | 3481 | throw ex; |
3489 | 3482 | } catch (Exception ex) { |
3490 | | - maybeFailEngine("acquire_directory_reader", ex); |
| 3483 | + maybeFailEngine("perform_action_directory_reader", ex); |
3491 | 3484 | ensureOpen(ex); // throw EngineCloseException here if we are already closed |
3492 | | - logger.error("failed to acquire directory reader", ex); |
3493 | | - throw new EngineException(shardId, "failed to acquire directory reader", ex); |
3494 | | - } |
3495 | | - } |
3496 | | - |
3497 | | - abstract static class DirectoryReaderSupplier implements Releasable { |
3498 | | - private final DirectoryReader directoryReader; |
3499 | | - private final AtomicBoolean released = new AtomicBoolean(false); |
3500 | | - |
3501 | | - DirectoryReaderSupplier(DirectoryReader directoryReader) { |
3502 | | - this.directoryReader = directoryReader; |
3503 | | - } |
3504 | | - |
3505 | | - public DirectoryReader getDirectoryReader() { |
3506 | | - return directoryReader; |
| 3485 | + logger.error("failed to perform action with directory reader", ex); |
| 3486 | + throw new EngineException(shardId, "failed to perform action with directory reader", ex); |
3507 | 3487 | } |
3508 | | - |
3509 | | - @Override |
3510 | | - public final void close() { |
3511 | | - if (released.compareAndSet(false, true)) { |
3512 | | - doClose(); |
3513 | | - } else { |
3514 | | - assert false : "DirectoryReaderSupplier was released twice"; |
3515 | | - } |
3516 | | - } |
3517 | | - |
3518 | | - abstract void doClose(); |
3519 | 3488 | } |
3520 | 3489 | } |
0 commit comments