Registers the {@code listener} to be called when an execution fails and the {@link RetryPolicy#withMaxRetries(int)
max retry attempts} or {@link RetryPolicy#withMaxDuration(Duration) max duration} are exceeded.
338909
public RetryPolicy<R> onRetriesExceeded(CheckedConsumer<? extends ExecutionCompletedEvent<R>> listener) {
    retriesExceededListener = EventListener.of(Assert.notNull(listener, "listener"));
    return this;
  }
507776
@SuppressWarnings("unchecked")
	private void register(final G gateway, final int attempt, final long timeoutMillis) {
		// eager check for canceling to avoid some unnecessary work
		if (canceled) {
			return;
		}

		try {
			log.info("Registration at {} attempt {} (timeout={}ms)", targetName, attempt, timeoutMillis);
			CompletableFuture<RegistrationResponse> registrationFuture = invokeRegistration(gateway, fencingToken, timeoutMillis);

			// if the registration was successful, let the TaskExecutor know
			CompletableFuture<Void> registrationAcceptFuture = registrationFuture.thenAcceptAsync(
				(RegistrationResponse result) -> {
					if (!isCanceled()) {
						if (result instanceof RegistrationResponse.Success) {
							// registration successful!
							S success = (S) result;
							completionFuture.complete(Tuple2.of(gateway, success));
						}
						else {
							// registration refused or unknown
							if (result instanceof RegistrationResponse.Decline) {
								RegistrationResponse.Decline decline = (RegistrationResponse.Decline) result;
								log.info("Registration at {} was declined: {}", targetName, decline.getReason());
							} else {
								log.error("Received unknown response to registration attempt: {}", result);
							}

							log.info("Pausing and re-attempting registration in {} ms", retryingRegistrationConfiguration.getRefusedDelayMillis());
							registerLater(gateway, 1, retryingRegistrationConfiguration.getInitialRegistrationTimeoutMillis(), retryingRegistrationConfiguration.getRefusedDelayMillis());
						}
					}
				},
				rpcService.getExecutor());

			// upon failure, retry
			registrationAcceptFuture.whenCompleteAsync(
				(Void v, Throwable failure) -> {
					if (failure != null && !isCanceled()) {
						if (ExceptionUtils.stripCompletionException(failure) instanceof TimeoutException) {
							// we simply have not received a response in time. maybe the timeout was
							// very low (initial fast registration attempts), maybe the target endpoint is
							// currently down.
							if (log.isDebugEnabled()) {
								log.debug("Registration at {} ({}) attempt {} timed out after {} ms",
									targetName, targetAddress, attempt, timeoutMillis);
							}

							long newTimeoutMillis = Math.min(2 * timeoutMillis, retryingRegistrationConfiguration.getMaxRegistrationTimeoutMillis());
							register(gateway, attempt + 1, newTimeoutMillis);
						}
						else {
							// a serious failure occurred. we still should not give up, but keep trying
							log.error("Registration at {} failed due to an error", targetName, failure);
							log.info("Pausing and re-attempting registration in {} ms", retryingRegistrationConfiguration.getErrorDelayMillis());

							registerLater(gateway, 1, retryingRegistrationConfiguration.getInitialRegistrationTimeoutMillis(), retryingRegistrationConfiguration.getErrorDelayMillis());
						}
					}
				},
				rpcService.getExecutor());
		}
		catch (Throwable t) {
			completionFuture.completeExceptionally(t);
			cancel();
		}
	}
1119046
public void addListener(PreInvalidationListener listener) {
    	if (preInvalidationListenerCount == 1 && tc.isDebugEnabled())
    		Tr.debug(tc, "Over-writing current PreInvalidationListener with new one");
        currentPreInvalidationListener = listener;
        preInvalidationListenerCount = 1;
    }
328848
def run_listener(listener)
      retry_count = 0

      begin
        listener.start
      rescue Exception => e
        handle_crashed_listener(listener, e, retry_count)
        retry_count += 1
        retry unless @signal_to_stop
      end
    rescue Exception => e
      log_error("Failed to run listener (#{e.message})", error_metadata(e))
      raise e
    end
375134
public RetryInterceptorBuilder<T> retryPolicy(RetryPolicy policy) {
		Assert.isNull(this.retryOperations,
				"cannot set the retry policy when a custom retryOperations has been set");
		Assert.isTrue(!this.templateAltered,
				"cannot set the retry policy if max attempts or back off policy or options changed");
		this.retryTemplate.setRetryPolicy(policy);
		this.retryPolicySet = true;
		this.templateAltered = true;
		return this;
	}
1363226
public void registerThrowable(RetryContext context, Throwable throwable) {
		((NeverRetryContext) context).setFinished();
		((RetryContextSupport) context).registerThrowable(throwable);
	}
1013160
public void registerListener(ConfigurationListener<?> listener) {
    if(!listeners.contains(listener)) {
      listeners.add(listener);
      Set<ConfigurationListener<?>> newListener = new HashSet<ConfigurationListener<?>>();
      newListener.add(listener);
      notifyListeners(newListener, liveConfigParser, log);
    }
  }
1294927
public void registerListener(JobID jobId, KvStateRegistryListener listener) {
		final KvStateRegistryListener previousValue = listeners.putIfAbsent(jobId, listener);

		if (previousValue != null) {
			throw new IllegalStateException("Listener already registered under " + jobId + '.');
		}
	}
72310
<T> T callWithRetries(Callable<T> callable, RecurringPolicy<?> recurringPolicy,
      RecurringStats retryStats, Set<Class<? extends Exception>> retryableExceptions,
      boolean recoverable, boolean logFailures) throws Exception {
    boolean recovery = retryStats != null;

    while (true) {
      try {
        return callable.call();
      } catch (Exception e) {
        ShutdownSignalException sse = extractCause(e, ShutdownSignalException.class);
        if (sse == null && logFailures && recurringPolicy != null
            && recurringPolicy.allowsAttempts())
          log.error("Invocation of {} failed.", callable, e);

        if (sse != null && (recovery || !recoverable))
          throw e;

        if (!closed) {
          try {
            // Retry on channel recovery failure or retryable exception
            boolean retryable =
                recurringPolicy != null && recurringPolicy.allowsAttempts()
                    && isRetryable(retryableExceptions, e, sse);
            long startTime = System.nanoTime();

            if (retryable) {
              if (retryStats == null) 
                retryStats = new RecurringStats(recurringPolicy);
                
              // Wait for pending recovery
              if (sse != null) {
                if (recurringPolicy.getMaxDuration() == null)
                  circuit.await();
                else if (!circuit.await(retryStats.getMaxWaitTime())) {
                  log.debug("Exceeded max wait time while waiting for {} to recover", this);
                  throw e;
                }
              }

              // Continue retries
              retryStats.incrementAttempts();
              if (!retryStats.isPolicyExceeded()) {
                long remainingWaitTime =
                    retryStats.getWaitTime().toNanos() - (System.nanoTime() - startTime);
                if (remainingWaitTime > 0)
                  retryWaiter.await(Duration.nanos(remainingWaitTime));
                continue;
              }
            }
          } catch (Throwable ignore) {
          }
        }

        throw e;
      }
    }
  }
527532
@Override
	public void registerThrowable(RetryContext context, Throwable throwable) {
		SimpleRetryContext simpleContext = ((SimpleRetryContext) context);
		simpleContext.registerThrowable(throwable);
	}
129740
public RetryTemplateBuilder withListener(RetryListener listener) {
		Assert.notNull(listener, "Listener should not be null");
		listenersList().add(listener);
		return this;
	}
1298398
@Override
    public void register(Object listener)
    {
        if (!(listener instanceof EventListener))
        {
            throw new IllegalArgumentException("Listener must implement EventListener");
        }
        listeners.add(((EventListener) listener));
    }
959245
public static <Return> Return retryUntilNoException(Callable<Return> callable, int maxTry, Class<? extends Throwable> exceptionClass) throws Exception {
        String errMsg = "连续重试失败" + maxTry + "次。";
        Exception t = null;
        while (maxTry > 0) {
            try {
                return callable.call();
            } catch (Exception throwable) {
                if (exceptionClass.isAssignableFrom(throwable.getClass())) {
                    //只对指定的异常重试，其他异常直接抛出去
                    maxTry--;
                    t = throwable;
                } else {
                    throw throwable;
                }
            }
        }
        LOG.error(new RuntimeException(errMsg, t));
        //这里是对重试N次后依然抛出指定异常的情况，原样抛出
        throw t;
    }
501183
@RestrictTo(LIBRARY)
	public void notifyFailedUseCase(AbstractException exception, UseCaseListener listener) {
		try {
			LOGGER.debug("Notifying " + getClass().getSimpleName() + " finish failed to listener " + listener.getClass().getSimpleName());
			listener.onFinishFailedUseCase(exception);
		} catch (Exception e) {
			AbstractException abstractException = wrapException(e);
			logHandledException(abstractException);
		}
	}
588849
@Override
  public void retryListener(QueryBatch batch, QueryBatchListener queryBatchListener) {
    // We get the batch and modify the client alone in order to make use
    // of the new forest client in case if the original host is unavailable.
    DatabaseClient client = null;
    Forest[] forests = batch.getBatcher().getForestConfig().listForests();
    for(Forest forest : forests) {
      if(forest.equals(batch.getForest()))
        client = getMoveMgr().getForestClient(forest);
    }
    QueryBatchImpl retryBatch = new QueryBatchImpl()
        .withClient( client )
        .withBatcher( batch.getBatcher() )
        .withTimestamp( batch.getTimestamp() )
        .withServerTimestamp( batch.getServerTimestamp() )
        .withItems( batch.getItems() )
        .withJobTicket( batch.getJobTicket() )
        .withJobBatchNumber( batch.getJobBatchNumber() )
        .withJobResultsSoFar( batch.getJobResultsSoFar() )
        .withForestBatchNumber( batch.getForestBatchNumber() )
        .withForestResultsSoFar( batch.getForestResultsSoFar() )
        .withForest( batch.getForest() )
        .withJobTicket( batch.getJobTicket() );
    queryBatchListener.processEvent(retryBatch);
  }
566762
public void setListeners(Collection<RetryListener> globalListeners) {
		ArrayList<RetryListener> retryListeners = new ArrayList<RetryListener>(
				globalListeners);
		AnnotationAwareOrderComparator.sort(retryListeners);
		this.globalListeners = retryListeners.toArray(new RetryListener[0]);
	}
1232603
public RetryInterceptorBuilder<T> maxAttempts(int maxAttempts) {
		Assert.isNull(this.retryOperations,
				"cannot alter the retry policy when a custom retryOperations has been set");
		Assert.isTrue(!this.retryPolicySet,
				"cannot alter the retry policy when a custom retryPolicy has been set");
		this.simpleRetryPolicy.setMaxAttempts(maxAttempts);
		this.retryTemplate.setRetryPolicy(this.simpleRetryPolicy);
		this.templateAltered = true;
		return this;
	}