class RateLimiterExecutor<R> extends PolicyExecutor<R> {
  private final RateLimiterImpl<R> rateLimiter;
  private final Duration maxWaitTime;

  public RateLimiterExecutor(RateLimiterImpl<R> rateLimiter, int policyIndex) {
    super(rateLimiter, policyIndex);
    this.rateLimiter = rateLimiter;
    maxWaitTime = rateLimiter.getConfig().getMaxWaitTime();
  }

  @Override
  protected ExecutionResult<R> preExecute() {
    try {
      return rateLimiter.tryAcquirePermit(maxWaitTime) ?
        null :
        ExecutionResult.exception(new RateLimitExceededException(rateLimiter));
    } catch (InterruptedException e) {
      // Set interrupt flag
      Thread.currentThread().interrupt();
      return ExecutionResult.exception(e);
    }
  }

  @Override
  protected CompletableFuture<ExecutionResult<R>> preExecuteAsync(Scheduler scheduler, FailsafeFuture<R> future) {<FILL_FUNCTION_BODY>}
}

    CompletableFuture<ExecutionResult<R>> promise = new CompletableFuture<>();
    long waitNanos = rateLimiter.reservePermits(1, maxWaitTime);
    if (waitNanos == -1)
      promise.complete(ExecutionResult.exception(new RateLimitExceededException(rateLimiter)));
    else {
      try {
        // Wait for the permit
        Future<?> permitWaitFuture = scheduler.schedule(() -> {
          // Signal for execution to proceed
          promise.complete(ExecutionResult.none());
          return null;
        }, waitNanos, TimeUnit.NANOSECONDS);

        // Propagate outer cancellations to the promise and permit wait future
        future.setCancelFn(this, (mayInterrupt, cancelResult) -> {
          promise.complete(cancelResult);
          permitWaitFuture.cancel(mayInterrupt);
        });
      } catch (Throwable t) {
        // Hard scheduling failure
        promise.completeExceptionally(t);
      }
    }

    return promise;
  
<methods>public Function<SyncExecutionInternal<R>,ExecutionResult<R>> apply(Function<SyncExecutionInternal<R>,ExecutionResult<R>>, dev.failsafe.spi.Scheduler) ,public Function<AsyncExecutionInternal<R>,CompletableFuture<ExecutionResult<R>>> applyAsync(Function<AsyncExecutionInternal<R>,CompletableFuture<ExecutionResult<R>>>, dev.failsafe.spi.Scheduler, FailsafeFuture<R>) ,public int getPolicyIndex() ,public ExecutionResult<R> postExecute(ExecutionInternal<R>, ExecutionResult<R>) <variables>private final non-sealed EventHandler<R> failureHandler,private final non-sealed FailurePolicy<R> failurePolicy,private final non-sealed int policyIndex,private final non-sealed EventHandler<R> successHandler