content: package com.aizuda.snailjob.client.core.strategy;
  
  import com.aizuda.snailjob.client.core.RetryExecutor;
  import com.aizuda.snailjob.client.core.RetryExecutorParameter;
  import com.aizuda.snailjob.client.core.intercepter.RetrySiteSnapshot;
  import com.aizuda.snailjob.client.core.retryer.RetryType;
  import com.aizuda.snailjob.client.core.retryer.RetryerInfo;
  import com.aizuda.snailjob.client.core.retryer.RetryerResultContext;
  import com.aizuda.snailjob.common.core.enums.RetryResultStatusEnum;
  import com.aizuda.snailjob.common.log.SnailJobLog;
  import com.github.rholder.retry.*;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.stereotype.Component;
  
  import java.util.Collections;
  import java.util.List;
  import java.util.concurrent.Callable;
  import java.util.concurrent.TimeUnit;
  import java.util.function.Consumer;
  
  /**
   * 执行远程重试
   *
   * @author: opensnail
   * @date : 2022-03-03 14:38
   * @since 1.3.0
   */
  @Component
  @Slf4j
  public class RemoteRetryStrategies extends AbstractRetryStrategies {
  
      @Override
      public boolean supports(int stage, RetryType retryType) {
          return RetrySiteSnapshot.EnumStage.REMOTE.getStage() == stage;
      }
  
      @Override
      protected void setStage() {
          RetrySiteSnapshot.setStage(RetrySiteSnapshot.EnumStage.REMOTE.getStage());
      }
  
      @Override
      protected Consumer<Object> doRetrySuccessConsumer(RetryerResultContext context) {
          return o -> {
              SnailJobLog.LOCAL.debug("RemoteRetryStrategies doRetrySuccessConsumer ");
          };
      }
  
      @Override
      protected void error(RetryerResultContext context) {
          context.setRetryResultStatusEnum(RetryResultStatusEnum.FAILURE);
      }
  
      @Override
      protected boolean preValidator(RetryerInfo retryerInfo, RetryerResultContext resultContext) {
          if (RetrySiteSnapshot.isRunning()) {
              resultContext.setRetryResultStatusEnum(RetryResultStatusEnum.FAILURE);
              resultContext.setMessage("Retry validation failed: reason: there is an ongoing retry task");
              return false;
          }
  
          return true;
      }
  
      @Override
      protected void unexpectedError(Exception e, RetryerResultContext retryerResultContext) {
          retryerResultContext.setRetryResultStatusEnum(RetryResultStatusEnum.SUCCESS);
      }
  
      @Override
      protected void success(RetryerResultContext retryerResultContext) {
          retryerResultContext.setRetryResultStatusEnum(RetryResultStatusEnum.SUCCESS);
      }
  
      @Override
      protected Consumer<Throwable> doGetRetryErrorConsumer(RetryerInfo retryerInfo, Object[] params) {
          return throwable -> {
              SnailJobLog.LOCAL.debug("RemoteRetryStrategies doGetRetryErrorConsumer ");
          };
      }
  
      @Override
      protected Callable doGetCallable(RetryExecutor<WaitStrategy, StopStrategy> retryExecutor, Object... params) {
          return () -> retryExecutor.execute(params);
      }
  
      @Override
      protected RetryExecutorParameter<WaitStrategy, StopStrategy> getRetryExecutorParameter(RetryerInfo retryerInfo) {
          return new RetryExecutorParameter<>() {
  
              @Override
              public WaitStrategy backOff() {
                  return WaitStrategies.fixedWait(1, TimeUnit.SECONDS);
              }
  
              @Override
              public StopStrategy stop() {
                  return StopStrategies.stopAfterAttempt(1);
              }
  
              @Override
              public List<RetryListener> getRetryListeners() {
                  return Collections.emptyList();
              }
          };
      }
  
  }
  