-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Control concurrency and add retry action in decommission flow #4684
Changes from all commits
b70a844
6a03e5e
aa498b6
5aa944f
9c6d073
ddc0baf
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 |
---|---|---|
|
@@ -18,6 +18,9 @@ | |
import org.opensearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsAction; | ||
import org.opensearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsRequest; | ||
import org.opensearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsResponse; | ||
import org.opensearch.action.admin.cluster.decommission.awareness.put.DecommissionAction; | ||
import org.opensearch.action.admin.cluster.decommission.awareness.put.DecommissionRequest; | ||
import org.opensearch.action.admin.cluster.decommission.awareness.put.DecommissionResponse; | ||
import org.opensearch.cluster.ClusterState; | ||
import org.opensearch.cluster.ClusterStateObserver; | ||
import org.opensearch.cluster.ClusterStateTaskConfig; | ||
|
@@ -72,6 +75,66 @@ public class DecommissionController { | |
this.threadPool = threadPool; | ||
} | ||
|
||
/** | ||
* This method sends a transport call to retry decommission action, given that - | ||
* 1. The request is not timed out | ||
* 2. And executed when there was a cluster manager change | ||
* | ||
* @param decommissionRequest decommission request object | ||
* @param startTime start time of previous request | ||
* @param listener callback for the retry action | ||
*/ | ||
public void retryDecommissionAction( | ||
DecommissionRequest decommissionRequest, | ||
long startTime, | ||
ActionListener<DecommissionResponse> listener | ||
) { | ||
final long remainingTimeoutMS = decommissionRequest.getRetryTimeout().millis() - (threadPool.relativeTimeInMillis() - startTime); | ||
if (remainingTimeoutMS <= 0) { | ||
logger.debug( | ||
"timed out before retrying [{}] for attribute [{}] after cluster manager change", | ||
DecommissionAction.NAME, | ||
decommissionRequest.getDecommissionAttribute() | ||
); | ||
listener.onFailure( | ||
new OpenSearchTimeoutException( | ||
"timed out before retrying [{}] for attribute [{}] after cluster manager change", | ||
DecommissionAction.NAME, | ||
decommissionRequest.getDecommissionAttribute() | ||
) | ||
); | ||
return; | ||
} | ||
decommissionRequest.setRetryOnClusterManagerChange(true); | ||
decommissionRequest.setRetryTimeout(TimeValue.timeValueMillis(remainingTimeoutMS)); | ||
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 will not be used in the new cluster manager . this retry timeout is checked only at the the time of cluster manager abdication and not anywhere else . Hence more than not (66% in case of 3 cluster manager setup), this parameter is never used , in scope of this PR . What are the cons of removing this altogether ? 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. For an unstable cluster having multiple leader switches, if not given a timeout, we might get stuck into endless loop of retrying and exhausting a transport thread. This timeout, helps to control the retry action. Although I agree, we might not hit this for a stable cluster. But I feel this will help to reject a work later on which the unstable cluster might not be able to execute |
||
transportService.sendRequest( | ||
transportService.getLocalNode(), | ||
DecommissionAction.NAME, | ||
decommissionRequest, | ||
new TransportResponseHandler<DecommissionResponse>() { | ||
@Override | ||
public void handleResponse(DecommissionResponse response) { | ||
listener.onResponse(response); | ||
} | ||
|
||
@Override | ||
public void handleException(TransportException exp) { | ||
listener.onFailure(exp); | ||
} | ||
|
||
@Override | ||
public String executor() { | ||
return ThreadPool.Names.SAME; | ||
} | ||
|
||
@Override | ||
public DecommissionResponse read(StreamInput in) throws IOException { | ||
return new DecommissionResponse(in); | ||
} | ||
} | ||
); | ||
} | ||
|
||
/** | ||
* Transport call to add nodes to voting config exclusion | ||
* | ||
|
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.
should we rename to
tryDecommissionOnNewClusterManager
as it is used only there for now ?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.
The controller, is more of generic methods which can be used in the service layer. This method is just attempting a retry and hence the name. The place where we are using it is during leader switch (one use case of it.
Let me know if you think it makes sense. I can rename it if required