34
34
import org .elasticsearch .core .TimeValue ;
35
35
import org .elasticsearch .index .IndexNotFoundException ;
36
36
import org .elasticsearch .node .NodeClosedException ;
37
+ import org .elasticsearch .tasks .CancellableTask ;
37
38
import org .elasticsearch .tasks .Task ;
38
39
import org .elasticsearch .threadpool .ThreadPool ;
39
40
import org .elasticsearch .transport .TransportService ;
@@ -91,28 +92,42 @@ protected void masterOperation(
91
92
final ClusterState unusedState ,
92
93
final ActionListener <ClusterHealthResponse > listener
93
94
) {
95
+ assert task instanceof CancellableTask ;
96
+ final CancellableTask cancellableTask = (CancellableTask ) task ;
94
97
95
98
final int waitCount = getWaitCount (request );
96
99
97
100
if (request .waitForEvents () != null ) {
98
- waitForEventsAndExecuteHealth (request , listener , waitCount , threadPool .relativeTimeInMillis () + request .timeout ().millis ());
101
+ waitForEventsAndExecuteHealth (
102
+ cancellableTask ,
103
+ request ,
104
+ listener ,
105
+ waitCount ,
106
+ threadPool .relativeTimeInMillis () + request .timeout ().millis ()
107
+ );
99
108
} else {
100
109
executeHealth (
110
+ cancellableTask ,
101
111
request ,
102
112
clusterService .state (),
103
113
listener ,
104
114
waitCount ,
105
- clusterState -> listener . onResponse ( getResponse ( request , clusterState , waitCount , TimeoutState .OK ) )
115
+ clusterState -> sendResponse ( cancellableTask , request , clusterState , waitCount , TimeoutState .OK , listener )
106
116
);
107
117
}
108
118
}
109
119
110
120
private void waitForEventsAndExecuteHealth (
121
+ final CancellableTask task ,
111
122
final ClusterHealthRequest request ,
112
123
final ActionListener <ClusterHealthResponse > listener ,
113
124
final int waitCount ,
114
125
final long endTimeRelativeMillis
115
126
) {
127
+ if (task .notifyIfCancelled (listener )) {
128
+ return ;
129
+ }
130
+
116
131
assert request .waitForEvents () != null ;
117
132
if (request .local ()) {
118
133
clusterService .submitStateUpdateTask (
@@ -129,11 +144,12 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
129
144
final TimeValue newTimeout = TimeValue .timeValueMillis (timeoutInMillis );
130
145
request .timeout (newTimeout );
131
146
executeHealth (
147
+ task ,
132
148
request ,
133
149
clusterService .state (),
134
150
listener ,
135
151
waitCount ,
136
- observedState -> waitForEventsAndExecuteHealth (request , listener , waitCount , endTimeRelativeMillis )
152
+ observedState -> waitForEventsAndExecuteHealth (task , request , listener , waitCount , endTimeRelativeMillis )
137
153
);
138
154
}
139
155
@@ -166,11 +182,12 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
166
182
assert newState .stateUUID ().equals (appliedState .stateUUID ())
167
183
: newState .stateUUID () + " vs " + appliedState .stateUUID ();
168
184
executeHealth (
185
+ task ,
169
186
request ,
170
187
appliedState ,
171
188
listener ,
172
189
waitCount ,
173
- observedState -> waitForEventsAndExecuteHealth (request , listener , waitCount , endTimeRelativeMillis )
190
+ observedState -> waitForEventsAndExecuteHealth (task , request , listener , waitCount , endTimeRelativeMillis )
174
191
);
175
192
}
176
193
@@ -187,7 +204,7 @@ public void onNoLongerMaster(String source) {
187
204
@ Override
188
205
public void onFailure (String source , Exception e ) {
189
206
if (e instanceof ProcessClusterEventTimeoutException ) {
190
- listener . onResponse ( getResponse ( request , clusterService .state (), waitCount , TimeoutState .TIMED_OUT ) );
207
+ sendResponse ( task , request , clusterService .state (), waitCount , TimeoutState .TIMED_OUT , listener );
191
208
} else {
192
209
logger .error (() -> new ParameterizedMessage ("unexpected failure during [{}]" , source ), e );
193
210
listener .onFailure (e );
@@ -199,21 +216,25 @@ public void onFailure(String source, Exception e) {
199
216
}
200
217
201
218
private void executeHealth (
219
+ final CancellableTask task ,
202
220
final ClusterHealthRequest request ,
203
221
final ClusterState currentState ,
204
222
final ActionListener <ClusterHealthResponse > listener ,
205
223
final int waitCount ,
206
224
final Consumer <ClusterState > onNewClusterStateAfterDelay
207
225
) {
226
+ if (task .notifyIfCancelled (listener )) {
227
+ return ;
228
+ }
208
229
209
230
if (request .timeout ().millis () == 0 ) {
210
- listener . onResponse ( getResponse ( request , currentState , waitCount , TimeoutState .ZERO_TIMEOUT ) );
231
+ sendResponse ( task , request , currentState , waitCount , TimeoutState .ZERO_TIMEOUT , listener );
211
232
return ;
212
233
}
213
234
214
235
final Predicate <ClusterState > validationPredicate = newState -> validateRequest (request , newState , waitCount );
215
236
if (validationPredicate .test (currentState )) {
216
- listener . onResponse ( getResponse ( request , currentState , waitCount , TimeoutState .OK ) );
237
+ sendResponse ( task , request , currentState , waitCount , TimeoutState .OK , listener );
217
238
} else {
218
239
final ClusterStateObserver observer = new ClusterStateObserver (
219
240
currentState ,
@@ -235,7 +256,7 @@ public void onClusterServiceClose() {
235
256
236
257
@ Override
237
258
public void onTimeout (TimeValue timeout ) {
238
- listener . onResponse ( getResponse ( request , observer .setAndGetObservedState (), waitCount , TimeoutState .TIMED_OUT ) );
259
+ sendResponse ( task , request , observer .setAndGetObservedState (), waitCount , TimeoutState .TIMED_OUT , listener );
239
260
}
240
261
};
241
262
observer .waitForNextChange (stateListener , validationPredicate , request .timeout ());
@@ -282,27 +303,32 @@ private enum TimeoutState {
282
303
ZERO_TIMEOUT
283
304
}
284
305
285
- private ClusterHealthResponse getResponse (
306
+ private void sendResponse (
307
+ final CancellableTask task ,
286
308
final ClusterHealthRequest request ,
287
- ClusterState clusterState ,
309
+ final ClusterState clusterState ,
288
310
final int waitFor ,
289
- TimeoutState timeoutState
311
+ final TimeoutState timeoutState ,
312
+ final ActionListener <ClusterHealthResponse > listener
290
313
) {
291
- ClusterHealthResponse response = clusterHealth (
292
- request ,
293
- clusterState ,
294
- clusterService .getMasterService ().numberOfPendingTasks (),
295
- allocationService .getNumberOfInFlightFetches (),
296
- clusterService .getMasterService ().getMaxTaskWaitTime ()
297
- );
298
- int readyCounter = prepareResponse (request , response , clusterState , indexNameExpressionResolver );
299
- boolean valid = (readyCounter == waitFor );
300
- assert valid || (timeoutState != TimeoutState .OK );
301
- // If valid && timeoutState == TimeoutState.ZERO_TIMEOUT then we immediately found **and processed** a valid state, so we don't
302
- // consider this a timeout. However if timeoutState == TimeoutState.TIMED_OUT then we didn't process a valid state (perhaps we
303
- // failed on wait_for_events) so this does count as a timeout.
304
- response .setTimedOut (valid == false || timeoutState == TimeoutState .TIMED_OUT );
305
- return response ;
314
+ ActionListener .completeWith (listener , () -> {
315
+ task .ensureNotCancelled ();
316
+ ClusterHealthResponse response = clusterHealth (
317
+ request ,
318
+ clusterState ,
319
+ clusterService .getMasterService ().numberOfPendingTasks (),
320
+ allocationService .getNumberOfInFlightFetches (),
321
+ clusterService .getMasterService ().getMaxTaskWaitTime ()
322
+ );
323
+ int readyCounter = prepareResponse (request , response , clusterState , indexNameExpressionResolver );
324
+ boolean valid = (readyCounter == waitFor );
325
+ assert valid || (timeoutState != TimeoutState .OK );
326
+ // If valid && timeoutState == TimeoutState.ZERO_TIMEOUT then we immediately found **and processed** a valid state, so we don't
327
+ // consider this a timeout. However if timeoutState == TimeoutState.TIMED_OUT then we didn't process a valid state (perhaps we
328
+ // failed on wait_for_events) so this does count as a timeout.
329
+ response .setTimedOut (valid == false || timeoutState == TimeoutState .TIMED_OUT );
330
+ return response ;
331
+ });
306
332
}
307
333
308
334
static int prepareResponse (
0 commit comments