|
40 | 40 | import org.elasticsearch.action.support.replication.ReplicationResponse;
|
41 | 41 | import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
|
42 | 42 | import org.elasticsearch.cluster.routing.ShardRouting;
|
| 43 | +import org.elasticsearch.common.CheckedRunnable; |
43 | 44 | import org.elasticsearch.common.StopWatch;
|
44 | 45 | import org.elasticsearch.common.bytes.BytesArray;
|
45 | 46 | import org.elasticsearch.common.bytes.BytesReference;
|
|
85 | 86 | import java.util.concurrent.CompletableFuture;
|
86 | 87 | import java.util.concurrent.ConcurrentLinkedDeque;
|
87 | 88 | import java.util.concurrent.CopyOnWriteArrayList;
|
| 89 | +import java.util.concurrent.atomic.AtomicBoolean; |
88 | 90 | import java.util.concurrent.atomic.AtomicInteger;
|
89 | 91 | import java.util.concurrent.atomic.AtomicLong;
|
90 | 92 | import java.util.function.Consumer;
|
@@ -223,7 +225,7 @@ && isTargetSameHistory()
|
223 | 225 | } else {
|
224 | 226 | final Engine.IndexCommitRef safeCommitRef;
|
225 | 227 | try {
|
226 |
| - safeCommitRef = shard.acquireSafeIndexCommit(); |
| 228 | + safeCommitRef = acquireSafeCommit(shard); |
227 | 229 | resources.add(safeCommitRef);
|
228 | 230 | } catch (final Exception e) {
|
229 | 231 | throw new RecoveryEngineException(shard.shardId(), 1, "snapshot failed", e);
|
@@ -395,17 +397,34 @@ public void onFailure(Exception e) {
|
395 | 397 | */
|
396 | 398 | private Releasable acquireStore(Store store) {
|
397 | 399 | store.incRef();
|
398 |
| - return Releasables.releaseOnce(() -> { |
399 |
| - final PlainActionFuture<Void> future = new PlainActionFuture<>(); |
400 |
| - assert threadPool.generic().isShutdown() == false; |
401 |
| - // TODO: We shouldn't use the generic thread pool here as we already execute this from the generic pool. |
402 |
| - // While practically unlikely at a min pool size of 128 we could technically block the whole pool by waiting on futures |
403 |
| - // below and thus make it impossible for the store release to execute which in turn would block the futures forever |
404 |
| - threadPool.generic().execute(ActionRunnable.run(future, store::decRef)); |
405 |
| - FutureUtils.get(future); |
| 400 | + return Releasables.releaseOnce(() -> runWithGenericThreadPool(store::decRef)); |
| 401 | + } |
| 402 | + |
| 403 | + /** |
| 404 | + * Releasing a safe commit can access some commit files. It's better not to use {@link CancellableThreads} to interact |
| 405 | + * with the file systems due to interrupt (see {@link org.apache.lucene.store.NIOFSDirectory} javadocs for more detail). |
| 406 | + * This method acquires a safe commit and wraps it to make sure that it will be released using the generic thread pool. |
| 407 | + */ |
| 408 | + private Engine.IndexCommitRef acquireSafeCommit(IndexShard shard) { |
| 409 | + final Engine.IndexCommitRef commitRef = shard.acquireSafeIndexCommit(); |
| 410 | + final AtomicBoolean closed = new AtomicBoolean(false); |
| 411 | + return new Engine.IndexCommitRef(commitRef.getIndexCommit(), () -> { |
| 412 | + if (closed.compareAndSet(false, true)) { |
| 413 | + runWithGenericThreadPool(commitRef::close); |
| 414 | + } |
406 | 415 | });
|
407 | 416 | }
|
408 | 417 |
|
| 418 | + private void runWithGenericThreadPool(CheckedRunnable<Exception> task) { |
| 419 | + final PlainActionFuture<Void> future = new PlainActionFuture<>(); |
| 420 | + assert threadPool.generic().isShutdown() == false; |
| 421 | + // TODO: We shouldn't use the generic thread pool here as we already execute this from the generic pool. |
| 422 | + // While practically unlikely at a min pool size of 128 we could technically block the whole pool by waiting on futures |
| 423 | + // below and thus make it impossible for the store release to execute which in turn would block the futures forever |
| 424 | + threadPool.generic().execute(ActionRunnable.run(future, task)); |
| 425 | + FutureUtils.get(future); |
| 426 | + } |
| 427 | + |
409 | 428 | static final class SendFileResult {
|
410 | 429 | final List<String> phase1FileNames;
|
411 | 430 | final List<Long> phase1FileSizes;
|
|
0 commit comments