-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Wait for cluster to recover before resolving index template #99797
Changes from 5 commits
3302980
fd4e882
1c13309
421f543
812154a
1cb5b35
49077a1
e07a5a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 99797 | ||
summary: Wait for cluster to recover before resolving index template | ||
area: CRUD | ||
type: bug | ||
issues: [] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -190,9 +190,9 @@ public static <Response extends ReplicationResponse & WriteResponse> ActionListe | |
} | ||
|
||
@Override | ||
protected void doExecute(Task task, BulkRequest bulkRequest, ActionListener<BulkResponse> listener) { | ||
protected void doExecute(Task task, BulkRequest bulkRequest, ActionListener<BulkResponse> originalListener) { | ||
/* | ||
* This is called on the Transport tread so we can check the indexing | ||
* This is called on the Transport thread so we can check the indexing | ||
* memory pressure *quickly* but we don't want to keep the transport | ||
* thread busy. Then, as soon as we have the indexing pressure in we fork | ||
* to one of the write thread pools. We do this because juggling the | ||
|
@@ -206,18 +206,58 @@ protected void doExecute(Task task, BulkRequest bulkRequest, ActionListener<Bulk | |
* We *could* detect these cases and only fork in then, but that is complex | ||
* to get right and the fork is fairly low overhead. | ||
*/ | ||
final ClusterState initialState = clusterService.state(); | ||
final int indexingOps = bulkRequest.numberOfActions(); | ||
final long indexingBytes = bulkRequest.ramBytesUsed(); | ||
final boolean isOnlySystem = isOnlySystem(bulkRequest, clusterService.state().metadata().getIndicesLookup(), systemIndices); | ||
final Releasable releasable = indexingPressure.markCoordinatingOperationStarted(indexingOps, indexingBytes, isOnlySystem); | ||
final ActionListener<BulkResponse> releasingListener = ActionListener.runBefore(listener, releasable::close); | ||
final boolean isOnlySystem = isOnlySystem(bulkRequest, initialState.metadata().getIndicesLookup(), systemIndices); | ||
final String executorName = isOnlySystem ? Names.SYSTEM_WRITE : Names.WRITE; | ||
threadPool.executor(Names.WRITE).execute(new ActionRunnable<>(releasingListener) { | ||
@Override | ||
protected void doRun() { | ||
doInternalExecute(task, bulkRequest, executorName, releasingListener); | ||
final Releasable releasable = indexingPressure.markCoordinatingOperationStarted(indexingOps, indexingBytes, isOnlySystem); | ||
// We should use the releasingListener from here onwards | ||
final ActionListener<BulkResponse> releasingListener = ActionListener.runBefore(originalListener, releasable::close); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a slight preference for leaving these lines in the same order to simplify the diff, unless I'm missing something about the new order being required? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was accidental. Should be reverted by now. |
||
|
||
final ClusterBlockException blockException = initialState.blocks().globalBlockedException(ClusterBlockLevel.WRITE); | ||
if (blockException != null) { | ||
if (false == blockException.retryable()) { | ||
releasingListener.onFailure(blockException); | ||
return; | ||
} | ||
}); | ||
logger.trace("cluster is blocked, waiting for it to recover", blockException); | ||
final ClusterStateObserver clusterStateObserver = new ClusterStateObserver( | ||
initialState, | ||
clusterService, | ||
bulkRequest.timeout(), | ||
logger, | ||
threadPool.getThreadContext() | ||
); | ||
clusterStateObserver.waitForNextChange(new ClusterStateObserver.Listener() { | ||
@Override | ||
public void onNewClusterState(ClusterState state) { | ||
threadPool.executor(Names.WRITE).execute(new ActionRunnable<>(releasingListener) { | ||
@Override | ||
protected void doRun() { | ||
doInternalExecute(task, bulkRequest, executorName, releasingListener); | ||
} | ||
}); | ||
} | ||
|
||
@Override | ||
public void onClusterServiceClose() { | ||
releasingListener.onFailure(new NodeClosedException(clusterService.localNode())); | ||
} | ||
|
||
@Override | ||
public void onTimeout(TimeValue timeout) { | ||
releasingListener.onFailure(blockException); | ||
} | ||
}, newState -> false == newState.blocks().hasGlobalBlockWithLevel(ClusterBlockLevel.WRITE)); | ||
} else { | ||
threadPool.executor(Names.WRITE).execute(new ActionRunnable<>(releasingListener) { | ||
@Override | ||
protected void doRun() { | ||
doInternalExecute(task, bulkRequest, executorName, releasingListener); | ||
} | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same as the Also I wonder why we're forking to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is now splitted into a separate method. I didn't do that because it felt too small for a method and not too big for a duplication. It is also possible to wrap the thing in a runnable so that it can be called in both places. But it feels wasteful to create an extra object. Please let me know if you have a preference.
Yeah. I noticed it as well when I duplicated the code. I think it is a bug. But would rather address it separately. |
||
} | ||
} | ||
|
||
protected void doInternalExecute(Task task, BulkRequest bulkRequest, String executorName, ActionListener<BulkResponse> listener) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nice way to enforce this is to extract the rest of this method out into another method which receives only the wrapped listener in its arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I thought about that, but somehow decided against for no particularly good reason. I have now split it into a separate method.