2025-05-27 20:44:22 -04:00
2025-05-28 09:57:36 -04:00
2025-05-27 20:53:49 -04:00

Async Extension for Activiti & APS

This library provides a way for administrators to assign asynchronous executors to specific process definitions or their activities.

Activiti executes activities in either the web container's thread pool or an internal AsyncExecutor. There are several AsyncExecutor implementations available, but the default implementation is a simple thread pool. All executions originating from the web container, like REST calls, will execute the processes and activities until they reach an asynchronous element. This could be any intermediary catching elements or any element marked as "Asynchronous". At that point, the execution becomes a job, queued for execution with a single AsyncExecutor implementation. This extension changes that single AsyncExecutor into 1-to-many via start-up system properties.

This project includes the base Activiti implementation in activiti-ext and the Alfresco Process Services enablement implementation in activiti-app-ext. Use both with APS and only the former with any other Activiti-based engine.

Installation

To use this extension, it depends on your Activiti implementation.

Without APS

You need to write some code to inject the SpringJobAwareAsyncExecutor or PojoJobAwareAsyncExecutor into your ProcessEngineConfiguration. This is very dependent on how your implementation is setup. Then you need to include this JAR in the classpath of your Activiti application. Once installed, remember to configure the extension as explained in the Configuration section below.

With APS

Include the JAR in the classpath of your APS application. This is best done by not changing the activiti-app.war file, but instead including it within the classpath using your web container configuration. For Apache Tomcat, you would add or modify the following context file: conf/Catalina/localhost/activiti-app.xml. Its related contents would be:

<Context>
        <Resources>
                <PostResources base="${catalina.base}/ext" className="org.apache.catalina.webresources.DirResourceSet" webAppMount="/WEB-INF/lib" readOnly="true" />
        </Resources>
</Context>

Notice the use of PostResources instead of PreResources. This library needs to be loaded after the web application. This is the best way to load any other extensions or customization to the Activiti App, including JavaDelegate implementations. If you use the -security switch, you will need to give this path permissions in the catalina.policy file:

grant codeBase "file:${catalina.base}/ext/-" {
	permission java.security.AllPermissions
}

Support Matrix

Extension APS
v1.0 v2.x+

Spring Configuration

This configuration is the same, whether you are using APS or the SpringJobAwareAsyncExecutor without APS. With the PojoJobAwareAsyncExecutor, configuration is defined by the developer who injected it into your application.

If no related properties are supplied, the SpringJobAwareAsyncExecutor will act as the DefaultAsyncJobExecutor. This means all asynchronous executions on all process definitions will use the same DefaultAsyncJobExecutor and its single shared thread pool. This is the default behavior, so no functionality is lost; but none is gained either.

To enable the feature, you will need to set some properties:

Property Description
inteligr8.async.executors.byProcessDefinitionKeys A comma, semi-colon, or pipe delimited list of process definition keys. A process definition key is the process ID as defined in the BPMN, which does not include version specifications. All asynchronous executions that originate in a listed process definition will use its own thread pool via its own AsyncExecutor. That executor is configurable as prescribed in the next table.
inteligr8.async.executors.byActivityIds A comma, semi-colon, or pipe delimited list of unique activity identifiers. An activity identifier includes the process definition key in which it is defined, combined with the activity ID of the asynchronous element. The process definition key is the process ID as defined in the BPMN, which does not include version specifications. An asynchronous element is any catching intermediary element or any activity with the "Asynchronous" flag. These executions will use their own thread pool via an AsyncExecutor. That executor is configurable as prescribed in the next table.

Any executions that do not match the above configurations will use the failsafe AsyncExecutor, which is the DefaultAsyncJobExecutor (or the default provided by APS).

To configure each individual executor, use the properties below. Substitute {id} with an enumerated value used in either list in the table above. The failsafe/fallback/default executor has an {id} of _fallback.

Property Default
inteligr8.async.executor.{id}.corePoolSize 1
inteligr8.async.executor.{id}.maxPoolSize 4
inteligr8.async.executor.{id}.queueSize 512
inteligr8.async.executor.{id}.keepAliveTimeMillis 5000
inteligr8.async.executor.{id}.defaultAsyncJobAcquireWaitTimeMillis 10000
inteligr8.async.executor.{id}.defaultTimerJobAcquireWaitTimeMillis 10000

Development

  • If you are not on APS and want to use the SpringJobAwareAsyncExecutor, it is a @Primary Spring bean of AsyncExecutor. You need to use it as a bean. If you construct it outside of the Spring context, it will not work. Use the PojoJobAwareAsyncExecutor instead.

Examples

inteligr8.async.executors.byProcessDefinitionKeys=routingProcess,generativeAiProcess
inteligr8.async.executors.byActivityIds=qualityControlProcess:unpackFiles
inteligr8.async.executor.routingProcess.maxCoreSize=6
inteligr8.async.executor.qualityControlProcess:unpackFiles.maxCoreSize=2
inteligr8.async.executor.qualityControlProcess:unpackFiles.queueSize=20
Description
No description provided
Readme 70 KiB
Languages
Java 82.3%
PowerShell 9.1%
Shell 8.6%