SpringBoot Activiti6.0 使用SharedExecutorServiceAsyncExecutor无法触发timer job 超时的问题

项目使用SpringBoot + activiti6.0,使用multi databases scheme方式实现saas多租户。

在@configuration类中使用MultiSchemaMultiTenantProcessEngineConfiguration创建activiti process engine configuration @bean,然后异步执行使用SharedExecutorServiceAsyncExecutor类。

MultiSchemaMultiTenantProcessEngineConfigurationImpl engineConfig = new MultiSchemaMultiTenantProcessEngineConfigurationImpl(holder);
    	engineConfig.setAsyncExecutorActivate(true);
    	engineConfig.setAsyncExecutor(new SharedExecutorServiceAsyncExecutor(holder));
    	engineConfig.setDatabaseType(MultiSchemaMultiTenantProcessEngineConfiguration.DATABASE_TYPE_POSTGRES);
    	engineConfig.setDatabaseSchemaUpdate(MultiSchemaMultiTenantProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);

然而,流程上的超时怎么也无法触发。

-----------------------

阅读了activiti源代码,发现activiti的acquireTimersJobs线程先会从act_ru_timers表中获取到即将执行的timers,然后将timers添加到act_ru_jobs表中,再由acquireAsyncJobs线程获取异步任务并触发任务。然而在执行触发前,DefaultJobManager都会询问process engine configuration上的asyncExecutor是否为active,而SharedExecutorServiceAsyncExecutor的active属性一直是false,也就无法触发任务了。

Class DefaultJobManager{ 
....
  protected boolean isAsyncExecutorActive() {
    return processEngineConfiguration.getAsyncExecutor().isActive();
  }
....
}

源代码中SharedExecutorServiceAsyncExecutor的start()中,不会将active设置为true。

 @Override
  public void start() {
    for (String tenantId : timerJobAcquisitionRunnables.keySet()) {
      startTimerJobAcquisitionForTenant(tenantId);
      startAsyncJobAcquisitionForTenant(tenantId);
      startResetExpiredJobsForTenant(tenantId);
    }
  }

而父类DefaultAsyncJobExecutor的start方法,在启动后会将isActive属性设置为true。

public void start() {
    if (isActive) {
      return;
    }

    log.info("Starting up the default async job executor [{}].", getClass().getName());
    
    if (timerJobRunnable == null) {
      timerJobRunnable = new AcquireTimerJobsRunnable(this, processEngineConfiguration.getJobManager());
    }
    
    if (resetExpiredJobsRunnable == null) {
      resetExpiredJobsRunnable = new ResetExpiredJobsRunnable(this);
    }
    
    if (!isMessageQueueMode && asyncJobsDueRunnable == null) {
      asyncJobsDueRunnable = new AcquireAsyncJobsDueRunnable(this);
    }
    
    if (!isMessageQueueMode) {
      initAsyncJobExecutionThreadPool();
      startJobAcquisitionThread();
    }
    
    startTimerAcquisitionThread();
    startResetExpiredJobsThread();

    isActive = true;

    executeTemporaryJobs();
  }

是SharedExecutorServiceAsyncExecutor的bug吗?还是需要额外设置active?

--------

调研了好久也没找到方法,但找到activiti还提供另外一种DefaultAsyncJobExecutor的实现-ExecutorPerTenantAsyncExecutor。而它的start()方法中很明显将active设置为true了。

public class ExecutorPerTenantAsyncExecutor implements TenantAwareAsyncExecutor {
....
  public void start() {
    for (AsyncExecutor asyncExecutor : tenantExecutors.values()) {
      asyncExecutor.start();
    }
    active = true;
  }
.....

}

于是直接修改@configuration代码一试,流程定义上的timers触发了。

@Bean
    public MultiSchemaMultiTenantProcessEngineConfiguration processEngineConfiguration(
            TenantInfoHolder holder) throws Exception {
    	MultiSchemaMultiTenantProcessEngineConfigurationImpl engineConfig = new MultiSchemaMultiTenantProcessEngineConfigurationImpl(holder);
    	engineConfig.setAsyncExecutorActivate(true);
    	engineConfig.setAsyncExecutor(new ExecutorPerTenantAsyncExecutor(holder));
    	engineConfig.setDatabaseType(MultiSchemaMultiTenantProcessEngineConfiguration.DATABASE_TYPE_POSTGRES);
    	engineConfig.setDatabaseSchemaUpdate(MultiSchemaMultiTenantProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);
    	
    	return engineConfig;
    }
    

----------

后话:关于activiti6.0实现multi tenant的网上资源不多,希望碰到类似问题的同学可以快速解决问题。

如果哪位老师知道SharedExecutorServiceAsyncExecutor的使用方法,希望可以回帖分享。

转载于:https://my.oschina.net/u/3706162/blog/1785664

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值