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

io.github.hpsocket.soa.starter.task.config.SoaTaskConfig Maven / Gradle / Ivy


package io.github.hpsocket.soa.starter.task.config;

import java.util.concurrent.Callable;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.task.ThreadPoolTaskExecutorCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.task.TaskDecorator;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import io.github.hpsocket.soa.framework.core.mdc.MdcAttr;
import io.github.hpsocket.soa.framework.web.support.WebServerHelper;
import io.github.hpsocket.soa.starter.task.aspect.ScheduledTraceIdInspector;
import io.github.hpsocket.soa.starter.task.properties.SoaTaskProperties;
import io.github.hpsocket.soa.starter.task.properties.SoaTaskProperties.Scheduling;

/** HP-SOA Task 配置 */
@EnableAsync
@EnableScheduling
@AutoConfiguration
@Import(ScheduledTraceIdInspector.class)
@EnableConfigurationProperties({SoaTaskProperties.class})
@ConditionalOnProperty(name = "spring.task.enabled", matchIfMissing = true)
public class SoaTaskConfig
{
    public static final String mdcTaskDecoratorBeanName = "mdcTaskDecorator";
    
    private SoaTaskProperties soaTaskProperties;
    
    public SoaTaskConfig(SoaTaskProperties soaTaskProperties)
    {
        this.soaTaskProperties = soaTaskProperties;
    }
    
    /** Task 任务装饰器(注入 {@linkplain org.slf4j.MDC MDC} 调用链跟踪信息)*/
    @Bean(mdcTaskDecoratorBeanName)
    @ConditionalOnMissingBean(name = mdcTaskDecoratorBeanName)
    TaskDecorator taskDecorator()
    {
        return new TaskDecorator()
        {    
            @Override
            public Runnable decorate(Runnable runnable)
            {
                MdcAttr mdcAttr = MdcAttr.fromMdc();
                
                return new Runnable()
                {
                    @Override
                    public void run()
                    {
                        try
                        {
                            mdcAttr.putMdc();
                            runnable.run();
                        }
                        finally
                        {
                            mdcAttr.removeMdc();
                        }
                    }
                };
            }
        };
    }
    
    @Bean
    ThreadPoolTaskExecutorCustomizer taskExecutorCustomizer()
    {
        return new ThreadPoolTaskExecutorCustomizer()
        {
            @Override
            public void customize(ThreadPoolTaskExecutor taskExecutor)
            {
                String executionRejectionPolicy = soaTaskProperties.getExecution().getPool().getRejectionPolicy();
                RejectedExecutionHandler rjh = WebServerHelper.parseRejectedExecutionHandler(executionRejectionPolicy, "CALLER_RUNS");                
                taskExecutor.setRejectedExecutionHandler(rjh);
            }
        };
    }
    
    @Bean
    @SuppressWarnings("serial")
    ThreadPoolTaskScheduler taskScheduler()
    {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler()
        {
            @Override
            protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler)
            {
                return new ScheduledThreadPoolExecutor(poolSize, threadFactory, rejectedExecutionHandler)
                {
                    @Override
                    public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit)
                    {
                        return super.schedule(wrapCommand(command), delay, unit);
                    }
                    
                    @Override
                    public  ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit)
                    {
                        return super.schedule(wrapCommand(callable), delay, unit);
                    }
                    
                    @Override
                    public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
                    {
                        return super.scheduleAtFixedRate(wrapCommand(command), initialDelay, period, unit);
                    }
                    
                    @Override
                    public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
                    {
                        return super.scheduleWithFixedDelay(wrapCommand(command), initialDelay, delay, unit);
                    }
                    
                    private Runnable wrapCommand(Runnable r)
                    {
                        return new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                MdcAttr mdcAttr = WebServerHelper.createMdcAttr();
                                
                                try
                                {
                                    mdcAttr.putMdc();
                                    r.run();
                                }
                                finally
                                {
                                    mdcAttr.removeMdc();
                                }
                            }
                        };
                    }
                    
                    private  Callable wrapCommand(Callable t)
                    {
                        return new Callable<>()
                        {
                            @Override
                            public T call()  throws Exception
                            {
                                MdcAttr mdcAttr = WebServerHelper.createMdcAttr();
                                
                                try
                                {
                                    mdcAttr.putMdc();
                                    return t.call();
                                }
                                finally
                                {
                                    mdcAttr.removeMdc();
                                }
                            }
                        };
                    }
                };
            }
        };
        
        Scheduling scheduling = soaTaskProperties.getScheduling();
        
        scheduler.setThreadNamePrefix(scheduling.getThreadNamePrefix());
        scheduler.setPoolSize(scheduling.getPool().getSize());
        scheduler.setWaitForTasksToCompleteOnShutdown(scheduling.getShutdown().isAwaitTermination());
        scheduler.setAwaitTerminationMillis(scheduling.getShutdown().getAwaitTerminationPeriod());

        String schedulingRejectionPolicy = scheduling.getPool().getRejectionPolicy();
        RejectedExecutionHandler rjh = WebServerHelper.parseRejectedExecutionHandler(schedulingRejectionPolicy, "ABORT");
        scheduler.setRejectedExecutionHandler(rjh);

        return scheduler;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy