@@ -158,6 +158,31 @@ public void run() {
158158 }
159159 }
160160
161+ private record TimedListener (ActionListener <Void > listener , Recorder recorder ) implements ActionListener <Void > {
162+
163+ @ Override
164+ public void onResponse (Void response ) {
165+ try (Releasable ignored = recorder .record ("listener.onResponse" )) {
166+ listener .onResponse (null );
167+ } catch (Exception e ) {
168+ assert false : e ;
169+ logger .error ("exception thrown by listener.onResponse" , e );
170+ }
171+ }
172+
173+ @ Override
174+ public void onFailure (Exception e ) {
175+ assert e != null ;
176+ try (Releasable ignored = recorder .record ("listener.onFailure" )) {
177+ listener .onFailure (e );
178+ } catch (Exception inner ) {
179+ e .addSuppressed (inner );
180+ assert false : e ;
181+ logger .error (() -> "exception thrown by listener.onFailure" , e );
182+ }
183+ }
184+ }
185+
161186 @ Override
162187 protected synchronized void doStop () {
163188 for (Map .Entry <TimeoutClusterStateListener , NotifyTimeout > onGoingTimeout : timeoutClusterStateListeners .entrySet ()) {
@@ -394,12 +419,14 @@ private void runTask(String source, Function<ClusterState, ClusterState> updateF
394419
395420 final long startTimeMillis = threadPool .relativeTimeInMillis ();
396421 final Recorder stopWatch = new Recorder (threadPool , slowTaskThreadDumpTimeout );
422+ final TimedListener timedListener = new TimedListener (clusterApplyListener , stopWatch );
397423 final ClusterState newClusterState ;
398424 try {
399425 try (Releasable ignored = stopWatch .record ("running task [" + source + ']' )) {
400426 newClusterState = updateFunction .apply (previousClusterState );
401427 }
402428 } catch (Exception e ) {
429+ timedListener .onFailure (e );
403430 TimeValue executionTime = getTimeSince (startTimeMillis );
404431 logger .trace (
405432 () -> format (
@@ -412,15 +439,14 @@ private void runTask(String source, Function<ClusterState, ClusterState> updateF
412439 e
413440 );
414441 warnAboutSlowTaskIfNeeded (executionTime , source , stopWatch );
415- clusterApplyListener .onFailure (e );
416442 return ;
417443 }
418444
419445 if (previousClusterState == newClusterState ) {
446+ timedListener .onResponse (null );
420447 TimeValue executionTime = getTimeSince (startTimeMillis );
421448 logger .debug ("processing [{}]: took [{}] no change in cluster state" , source , executionTime );
422449 warnAboutSlowTaskIfNeeded (executionTime , source , stopWatch );
423- clusterApplyListener .onResponse (null );
424450 } else {
425451 if (logger .isTraceEnabled ()) {
426452 logger .debug ("cluster state updated, version [{}], source [{}]\n {}" , newClusterState .version (), source , newClusterState );
@@ -430,6 +456,7 @@ private void runTask(String source, Function<ClusterState, ClusterState> updateF
430456 try {
431457 setIsApplyingClusterState ();
432458 applyChanges (previousClusterState , newClusterState , source , stopWatch );
459+ timedListener .onResponse (null );
433460 TimeValue executionTime = getTimeSince (startTimeMillis );
434461 logger .debug (
435462 "processing [{}]: took [{}] done applying updated cluster state (version: {}, uuid: {})" ,
@@ -439,8 +466,11 @@ private void runTask(String source, Function<ClusterState, ClusterState> updateF
439466 newClusterState .stateUUID ()
440467 );
441468 warnAboutSlowTaskIfNeeded (executionTime , source , stopWatch );
442- clusterApplyListener .onResponse (null );
443469 } catch (Exception e ) {
470+ // failing to apply a cluster state with an exception indicates a bug in validation or in one of the appliers; if we
471+ // continue we will retry with the same cluster state but that might not help.
472+ assert applicationMayFail ();
473+ timedListener .onFailure (e );
444474 TimeValue executionTime = getTimeSince (startTimeMillis );
445475 if (logger .isTraceEnabled ()) {
446476 logger .warn (() -> format ("""
@@ -460,10 +490,6 @@ private void runTask(String source, Function<ClusterState, ClusterState> updateF
460490 e
461491 );
462492 }
463- // failing to apply a cluster state with an exception indicates a bug in validation or in one of the appliers; if we
464- // continue we will retry with the same cluster state but that might not help.
465- assert applicationMayFail ();
466- clusterApplyListener .onFailure (e );
467493 } finally {
468494 clearIsApplyingClusterState ();
469495 }
0 commit comments