package com.jay.monitor.data.server.componts;

import com.jay.monitor.data.server.factory.AbstractThreadProcess;
import com.jay.monitor.data.server.report.alert.AlertDataService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 定时开启调度线程
 *
 * @author liukaixiong
 * @Email liukx@elab-plus.com
 * @date 2021/9/8 - 10:18
 */
@Component
public class TaskSmartLifecycle implements SmartLifecycle {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private List<AbstractThreadProcess> threadProcesses;

    @Autowired
    private AlertDataService alertDataService;

    private ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1);

    /**
     * 开启调度标记
     */
    private volatile boolean isRunning = false;

    @Override
    public void start() {
        // 调度线程. 如果在集群环境下，需要保持每个节点的数据最终一致性
        executor.scheduleWithFixedDelay(() -> alertDataService.refreshCache(), 0, 5, TimeUnit.MINUTES);

        for (AbstractThreadProcess threadProcess : threadProcesses) {
            String threadName = threadProcess.getThreadName();
            logger.debug("启动消费线程:" + threadName + "\t" + threadProcess);
            Thread thread = new Thread(threadProcess, threadName);
            thread.setUncaughtExceptionHandler((currentThread, throwable) -> {
                logger.error("极端异常出现未捕获的情况:" + currentThread.getName(), throwable);
            });
            thread.start();
        }
        isRunning = true;
    }

    @Override
    public void stop() {
        for (AbstractThreadProcess threadProcess : threadProcesses) {
            threadProcess.stop();
            logger.warn("容器停止，触发stop关闭消费线程:" + threadProcess.getThreadName());
        }
        isRunning = false;
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }
}
