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

com.huaweicloud.dws.client.worker.ExecutionPool Maven / Gradle / Ivy

package com.huaweicloud.dws.client.worker;

import com.huaweicloud.dws.client.DwsClient;
import com.huaweicloud.dws.client.DwsConfig;
import com.huaweicloud.dws.client.action.AbstractAction;
import com.huaweicloud.dws.client.collector.ActionCollector;
import com.huaweicloud.dws.client.exception.DwsClientException;
import com.huaweicloud.dws.client.exception.ExceptionCode;
import com.huaweicloud.dws.client.util.AssertUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ProjectName: dws-connector
 * @ClassName: ExecutionPool
 * @Description: 资源池
 * @Date: 2023/1/9 19:06
 * @Version: 1.0
 */
@Slf4j
public class ExecutionPool implements Closeable {

    public static final long AWAIT_TIME = 500L;

    private final String name;

    /**
     * 所有的执行者(按照并发,每个初始化一个执行者)
     */
    private final ActionExecutor[] executors;

    /**
     * 后台任务执行
     */
    private final BackgroundExecutor backgroundJob;

    /**
     * 配置
     */
    private final DwsConfig config;

    /**
     * 是否在运行
     */
    private final AtomicBoolean started;

    /**
     * 执行任务线程池
     */
    private ExecutorService workerExecutorService;
    private final ThreadFactory workerThreadFactory;

    /**
     * 后台任务线程池
     */
    private ExecutorService backgroundExecutorService;
    private final ThreadFactory backgroundThreadFactory;

    /**
     * 程序关闭时回调任务
     */
    private Thread shutdownHandler = null;
    private final ActionCollector collector;

    public ActionCollector getCollector() {
        return collector;
    }

    public ExecutionPool(String name, DwsConfig config, DwsClient client) {
        this.name = name;
        this.config = config;
        this.collector = new ActionCollector(config, this);
        workerThreadFactory = new ThreadFactory() {
            private final AtomicInteger threadNumber = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setName(name + "-worker-" + threadNumber.getAndIncrement());
                t.setDaemon(true);
                return t;
            }
        };

        backgroundThreadFactory = new ThreadFactory() {
            private final AtomicInteger threadNumber = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setName(name + "-background-" + threadNumber.getAndIncrement());
                t.setDaemon(true);
                return t;
            }
        };
        started = new AtomicBoolean(false);
        backgroundJob = new BackgroundExecutor(config, started, collector, client);
        executors = new ActionExecutor[config.getThreadSize()];
        for (int i = 0; i < config.getThreadSize(); i++) {
            executors[i] = new ActionExecutor(started, config);
        }
        start();
    }

    private synchronized void start() {
        if (started.compareAndSet(false, true)) {
            log.info("Execution Pool start name = {}", name);
            // 初始化线程池
            workerExecutorService = new ThreadPoolExecutor(config.getThreadSize(), config.getThreadSize(), 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1), workerThreadFactory, new ThreadPoolExecutor.AbortPolicy());
            backgroundExecutorService = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1), backgroundThreadFactory, new ThreadPoolExecutor.AbortPolicy());
            for (int i = 0; i < executors.length; i++) {
                // 把每个干活的都拉起来
                workerExecutorService.execute(executors[i]);
            }
            // 后台任务开始跑起来
            backgroundExecutorService.execute(backgroundJob);
            // 系统停止时执行关闭
            Runtime.getRuntime().addShutdownHook(shutdownHandler = new Thread(this::close));
        }
    }

    public boolean isRunning() {
        return started.get();
    }

    public boolean submit(AbstractAction action) throws DwsClientException {
        // 已经close的不允许提交
        AssertUtil.isTrue(isRunning(), new DwsClientException(ExceptionCode.ALREADY_CLOSE, "this pool is closed."));
        // 尝试在每个任务执行器上提交执行
        for (ActionExecutor executor : executors) {
            // 寻找一个空闲的executor 执行该任务
            if (executor.submit(action)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查后台任务是否有异常
     */
    public void tryException() throws DwsClientException {
        backgroundJob.tryException();
    }

    @Override
    public void close() {
        try {
            // 先停止后台任务后再关闭资源
            backgroundJob.close();
        } catch (IOException e) {
            log.error("", e);
        }
        if (started.compareAndSet(true, false)) {
            for (ActionExecutor executor : executors) {
                try {
                    executor.close();
                } catch (IOException e) {
                    log.error("", e);
                }
            }
            try {
                backgroundExecutorService.shutdown();
                while (!backgroundExecutorService.awaitTermination(AWAIT_TIME, TimeUnit.MILLISECONDS)) {
                    log.info("wait background executorService termination[{}]", name);
                }
            } catch (Exception e) {
                log.error("shutdown background error.", e);
            }
            backgroundExecutorService = null;
            try {
                workerExecutorService.shutdown();
                while (!workerExecutorService.awaitTermination(AWAIT_TIME, TimeUnit.MILLISECONDS)) {
                    log.info("wait worker executorService termination[{}]", name);
                }
                workerExecutorService = null;
            } catch (Exception e) {
                log.error("shutdown worker error.", e);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy