All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arextest.schedule.resume.SelfHealingExecutorImpl Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
package com.arextest.schedule.resume;

import com.arextest.schedule.bizlog.BizLogger;
import com.arextest.schedule.dao.mongodb.ReplayActionCaseItemRepository;
import com.arextest.schedule.dao.mongodb.ReplayActionCaseItemRepository.GroupCountRes;
import com.arextest.schedule.dao.mongodb.ReplayPlanActionRepository;
import com.arextest.schedule.dao.mongodb.ReplayPlanRepository;
import com.arextest.schedule.mdc.MDCTracer;
import com.arextest.schedule.model.OperationTypeData;
import com.arextest.schedule.model.ReplayActionItem;
import com.arextest.schedule.model.ReplayPlan;
import com.arextest.schedule.planexecution.PlanExecutionMonitor;
import com.arextest.schedule.progress.ProgressEvent;
import com.arextest.schedule.progress.ProgressTracer;
import com.arextest.schedule.service.ConfigurationService;
import com.arextest.schedule.service.PlanConsumePrepareService;
import com.arextest.schedule.service.PlanConsumeService;
import com.arextest.schedule.utils.ReplayParentBinder;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

/**
 * @author jmo
 * @since 2021/10/12
 */
@Component
@Slf4j
public class SelfHealingExecutorImpl implements SelfHealingExecutor {

  @Resource
  private ReplayPlanRepository replayPlanRepository;
  @Resource
  private ReplayPlanActionRepository replayPlanActionRepository;
  @Resource
  private ReplayActionCaseItemRepository replayActionCaseItemRepository;
  @Resource
  private ConfigurationService configurationService;
  @Resource
  private ProgressEvent progressEvent;
  @Resource
  private ProgressTracer progressTracer;
  @Resource
  private PlanConsumeService planConsumeService;
  @Resource
  private PlanConsumePrepareService planConsumePrepareService;
  @Resource
  private PlanExecutionMonitor planExecutionMonitorImpl;

  // #TODO There is a problem here, Date and Duration types are compared
  public void defaultSelfHealing(Duration offsetDuration, Duration maxDuration) {
    List timeoutPlans = queryTimeoutPlan(offsetDuration, maxDuration);
    if (CollectionUtils.isEmpty(timeoutPlans)) {
      return;
    }
    long durationMillis = offsetDuration.toMillis();
    for (ReplayPlan replayPlan : timeoutPlans) {
      String planId = replayPlan.getId();
      MDCTracer.addPlanId(planId);
      try {
        if (isRunning(planId, durationMillis)) {
          LOGGER.warn("skip resume when the plan running, plan id: {} , timeout millis {},", planId,
              durationMillis);
          continue;
        }
        doResume(replayPlan);
      } catch (Throwable throwable) {
        LOGGER.error("do resume plan error:{} ,plan id: {}", throwable.getMessage(), planId,
            throwable);
      }
    }
    MDCTracer.clear();
  }

  public List queryTimeoutPlan(Duration offsetDuration, Duration maxDuration) {
    return replayPlanRepository.timeoutPlanList(offsetDuration, maxDuration);
  }

  public void doResume(ReplayPlan replayPlan) {
    long planCreateMillis = System.currentTimeMillis();
    replayPlan.setPlanCreateMillis(planCreateMillis);
    String planId = replayPlan.getId();
    List actionItems = replayPlanActionRepository.queryPlanActionList(planId);
    if (CollectionUtils.isEmpty(actionItems)) {
      LOGGER.warn("skip resume when the plan empty action list, plan id: {} mark to finish ",
          planId);
      progressEvent.onReplayPlanFinish(replayPlan);
      return;
    }
    ConfigurationService.ScheduleConfiguration schedule =
        configurationService.schedule(replayPlan.getAppId());
    if (schedule != null) {
      replayPlan.setReplaySendMaxQps(schedule.getSendMaxQps());
    }
    replayPlan.setReplayActionItemList(actionItems);
    replayPlan.setResumed(true);
    BizLogger.recordResumeRun(replayPlan);
    planConsumePrepareService.doResumeOperationDescriptor(replayPlan);
    doResumeLastRecordTime(actionItems);
    ReplayParentBinder.setupReplayActionParent(actionItems, replayPlan);
    LOGGER.info("try resume the plan running, plan id: {}", planId);
    planExecutionMonitorImpl.register(replayPlan);
    planConsumeService.runAsyncConsume(replayPlan);
  }

  private void doResumeLastRecordTime(List actionItems) {
    for (ReplayActionItem actionItem : actionItems) {
      List groupCountResList = replayActionCaseItemRepository.getLastRecord(
          actionItem.getId());
      if (CollectionUtils.isEmpty(groupCountResList)) {
        continue;
      }
      List operationTypeDataList = new ArrayList<>();
      for (GroupCountRes groupCountRes : groupCountResList) {
        OperationTypeData operationTypeData = new OperationTypeData(groupCountRes.getCaseType());
        if (groupCountRes.getCount() != null) {
          operationTypeData.setTotalLoadedCount(groupCountRes.getCount());
        }
        if (groupCountRes.getLastRecordTime() != null) {
          operationTypeData.setLastRecordTime(groupCountRes.getLastRecordTime());
        }
        operationTypeDataList.add(operationTypeData);
      }
      actionItem.setOperationTypes(operationTypeDataList);
    }
  }

  private boolean isRunning(String planId, long timeoutMillis) {
    long now = System.currentTimeMillis();
    long lastUpdateTime = progressTracer.lastUpdateTime(planId);
    return (now - lastUpdateTime) < timeoutMillis;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy