-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Discard intermediate results upon cancellation for stats endpoints #82685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
gmarouli
merged 31 commits into
elastic:master
from
gmarouli:stats-discard-intermediate-results-on-cancellation
Feb 10, 2022
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
bc9bc00
CancellableTask can notify registered listeners
gmarouli 81f88a2
Test case to show the bug
gmarouli 0243f24
Discard intermediate results upon cancellation
gmarouli 4eec5fa
Fix format
gmarouli c18eaad
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
elasticmachine 30666ba
Fix test
gmarouli e8dd984
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
elasticmachine b1e833b
Introduce intermediate node response collector
gmarouli 21460c6
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
gmarouli 89230a4
Test IntermediateNodeResponses
gmarouli 583dc06
Fix deadlock
gmarouli 78e0292
Fix prematurely closing the listener
gmarouli b07aa5c
Test TransportBroadcastByNodeAction
gmarouli df76008
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
gmarouli 1433a98
Listener will always be notified when cancelled
gmarouli ccbc336
Bug fix, wrap failures with FailedNodeException
gmarouli e7ac678
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
elasticmachine 2224e1c
Propagate the task cancellation to the listener
gmarouli 3e73db9
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
gmarouli 51ab1ef
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
gmarouli 62a2c24
Enrich javadoc
gmarouli 660c16b
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
gmarouli f54a7ac
Polishing NodeResponseTracker
gmarouli 21663a0
Update docs/changelog/82685.yaml
gmarouli e596a61
Merge maybeAddResponse and isComplete
gmarouli e867b69
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
gmarouli 48ae87c
Improve listener addition and add assertions
gmarouli a614cd8
Simplify tracking nodes responding after discarding
gmarouli c28e535
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
elasticmachine aa5adbd
Merge branch 'master' into stats-discard-intermediate-results-on-canc…
elasticmachine 34437cf
Bug fix
gmarouli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| pr: 82685 | ||
| summary: Discard intermediate results upon cancellation for stats endpoints | ||
| area: Stats | ||
| type: bug | ||
| issues: | ||
| - 82337 | ||
97 changes: 97 additions & 0 deletions
97
server/src/main/java/org/elasticsearch/action/support/NodeResponseTracker.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
| * in compliance with, at your election, the Elastic License 2.0 or the Server | ||
| * Side Public License, v 1. | ||
| */ | ||
|
|
||
| package org.elasticsearch.action.support; | ||
|
|
||
| import java.util.Collection; | ||
| import java.util.concurrent.atomic.AtomicInteger; | ||
| import java.util.concurrent.atomic.AtomicReferenceArray; | ||
|
|
||
| /** | ||
| * This class tracks the intermediate responses that will be used to create aggregated cluster response to a request. It also gives the | ||
| * possibility to discard the intermediate results when asked, for example when the initial request is cancelled, in order to release the | ||
| * resources. | ||
| */ | ||
| public class NodeResponseTracker { | ||
|
|
||
| private final AtomicInteger counter = new AtomicInteger(); | ||
| private final int expectedResponsesCount; | ||
| private volatile AtomicReferenceArray<Object> responses; | ||
| private volatile Exception causeOfDiscarding; | ||
|
|
||
| public NodeResponseTracker(int size) { | ||
| this.expectedResponsesCount = size; | ||
| this.responses = new AtomicReferenceArray<>(size); | ||
| } | ||
|
|
||
| public NodeResponseTracker(Collection<Object> array) { | ||
| this.expectedResponsesCount = array.size(); | ||
| this.responses = new AtomicReferenceArray<>(array.toArray()); | ||
| } | ||
|
|
||
| /** | ||
| * This method discards the results collected so far to free up the resources. | ||
| * @param cause the discarding, this will be communicated if they try to access the discarded results | ||
| */ | ||
| public void discardIntermediateResponses(Exception cause) { | ||
| if (responses != null) { | ||
| this.causeOfDiscarding = cause; | ||
| responses = null; | ||
| } | ||
| } | ||
|
|
||
| public boolean responsesDiscarded() { | ||
| return responses == null; | ||
| } | ||
|
|
||
| /** | ||
| * This method stores a new node response if the intermediate responses haven't been discarded yet. If the responses are not discarded | ||
| * the method asserts that this is the first response encountered from this node to protect from miscounting the responses in case of a | ||
| * double invocation. If the responses have been discarded we accept this risk for simplicity. | ||
| * @param nodeIndex, the index that represents a single node of the cluster | ||
| * @param response, a response can be either a NodeResponse or an error | ||
| * @return true if all the nodes' responses have been received, else false | ||
| */ | ||
| public boolean trackResponseAndCheckIfLast(int nodeIndex, Object response) { | ||
| AtomicReferenceArray<Object> responses = this.responses; | ||
|
|
||
| if (responsesDiscarded() == false) { | ||
| boolean firstEncounter = responses.compareAndSet(nodeIndex, null, response); | ||
| assert firstEncounter : "a response should be tracked only once"; | ||
| } | ||
| return counter.incrementAndGet() == getExpectedResponseCount(); | ||
| } | ||
|
|
||
| /** | ||
| * Returns the tracked response or null if the response hasn't been received yet for a specific index that represents a node of the | ||
| * cluster. | ||
| * @throws DiscardedResponsesException if the responses have been discarded | ||
| */ | ||
| public Object getResponse(int nodeIndex) throws DiscardedResponsesException { | ||
| AtomicReferenceArray<Object> responses = this.responses; | ||
| if (responsesDiscarded()) { | ||
| throw new DiscardedResponsesException(causeOfDiscarding); | ||
| } | ||
| return responses.get(nodeIndex); | ||
| } | ||
|
|
||
| public int getExpectedResponseCount() { | ||
| return expectedResponsesCount; | ||
| } | ||
|
|
||
| /** | ||
| * This exception is thrown when the {@link NodeResponseTracker} is asked to give information about the responses after they have been | ||
| * discarded. | ||
| */ | ||
| public static class DiscardedResponsesException extends Exception { | ||
|
|
||
| public DiscardedResponsesException(Exception cause) { | ||
| super(cause); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.