package com.cm.websocket.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: ScheduledConfig
 * @Description:
 * @Author: WangGeng
 * @Date: 2020/9/26 12:01
 * @Version: 1.0
 **/
@Configuration
public class ScheduledConfig {
    // 核心线程数（默认线程数）
    private static final int CORE_POOL_SIZE = 100;
    // 最大线程数
    private static final int MAX_POOL_SIZE = 500;
    // 允许线程空闲时间（单位：默认为秒）
    private static final int KEEP_ALIVE_TIME = 10;
    // 缓冲队列数
    private static final int QUEUE_CAPACITY = 500;
    // 线程池名前缀
    private static final String THREAD_NAME_PREFIX = "Async-Service-";

    @Bean("taskExecutor") // bean的名称，默认为首字母小写的方法名
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(CORE_POOL_SIZE);
        executor.setMaxPoolSize(MAX_POOL_SIZE);
        executor.setQueueCapacity(QUEUE_CAPACITY);
        executor.setKeepAliveSeconds(KEEP_ALIVE_TIME);
        executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
        /**
         * 线程池对拒绝任务的处理策略:
         * 1. CallerRunsPolicy ：这个策略重试添加当前的任务，他会自动重复调用 execute() 方法，直到成功。
         *
         * 2. AbortPolicy ：对拒绝任务抛弃处理，并且抛出异常。
         *
         * 3. DiscardPolicy ：对拒绝任务直接无声抛弃，没有异常信息。
         *
         * 4. DiscardOldestPolicy ：对拒绝任务不抛弃，而是抛弃队列里面等待最久的一个线程，然后把拒绝任务加到队列。
         */
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        // 初始化
        executor.initialize();
        return executor;
    }

    /**
     * @author:XingWL
     * @description:任务调度器，解决和WebSocket冲突
     * @date: 2020/8/3 16:27
     */
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(50);
        scheduler.initialize();
        return scheduler;
    }
}
