package com.friday.distributor.scheduler.poller;

import com.friday.distributor.statemachine.TaskStateMachineHelper;
import com.friday.base.common.response.DubboResult;
import com.friday.base.redis.annotation.Rlock;
import com.friday.distributor.bean.Job;
import com.friday.distributor.bean.TaieJobExecInfo;
import com.friday.distributor.frame.GeneralStrategyContext;
import com.friday.distributor.mapper.QueueMapper;
import com.friday.distributor.po.QueuePo;
import com.friday.distributor.queue.TaskQueueManager;
import com.friday.distributor.service.DistributorExecuteService;
import com.friday.operation.api.distributor.constant.TaieJobState;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author YaoYao
 * @Date Created In 14:10 2023/3/8
 * @Description
 * @Modified By
 */
@Slf4j
@Service
public class PollingHelper {
    @Autowired
    private GeneralStrategyContext generalStrategy;
    @Autowired
    private TaskQueueManager taskQueueManager;
    @Autowired
    private QueueMapper queueMapper;
    @Autowired
    private TaskStateMachineHelper taskStateMachineHelper;
    @Autowired
    private DistributorExecuteService executeService;

    @Rlock(localKey = "TAIE-MutexPolling + #queueKey")
    public void mutexPolling(String queueKey, List<Job> rankedJobs){
        if(taskQueueManager.mutexQueue(queueKey)){
            return;
        }
        queueMapper.updateQueueByKey(QueuePo.builder()
                .key(queueKey)
                .mutex(true)
                .build());
        rankedJobs.forEach(job -> executeService.asyncStartTaieJob(job));
        queueMapper.updateQueueByKey(QueuePo.builder()
                .key(queueKey)
                .mutex(false)
                .build());
    }

    @Async(value = "queuePollingExecutor")
    public void generalPolling(String qKey, Job job){
        try {
            DubboResult<TaieJobExecInfo> execInfoResult = generalStrategy.getTaieJobExecDetail(job);
            if(execInfoResult.success()){
                TaieJobExecInfo execInfo = execInfoResult.getObject();
                taskStateMachineHelper.dealOnJobState(TaieJobState.valueOf(execInfo.getJobState()), job);
                taskQueueManager.updateJob(job, qKey);
            }
        } catch (Exception e){
            log.error("子任务状态轮询异常, invokeId = {}", job.getInvokeId(), e);
        }
    }


}
