cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring Job executor thread pool

spark2
Champ in-the-making
Champ in-the-making
I see below variables in DefaultJobExecutor

  protected int queueSize = 3;
  protected int corePoolSize = 3;
  private int maxPoolSize = 10;


I am performing load testing on basic workflow (Start -> Java Service Task -> End)
The delegate class just prints System.out

It runs fine for 10-15 threads. but when i launch over 50 threads, it freezes forever and have to kill the process.
I believe this is due to thread pool configuration, But will do more test and probably run in JProfiler to find more.
For this test, I used Oracle Database with BoneCP

1) Is it possible to configure thread pool in activiti.cfg.xml
2) Is it possible to configure our own Thread pool implementation

Thanks
5 REPLIES 5

trademak
Star Contributor
Star Contributor
You can inject your own DefaultJobExecutor bean in the jobExecutor property of the ProcessEngineConfiguration. And then you can configure these values. To fully customise the job executor behaviour you can use your own JobExecutor implementation.

Best regards,

spark2
Champ in-the-making
Champ in-the-making
Thanks for your response.

We have requirement for multiple instances of a workflow having async task to run concurrently.
The service task code is non-transactional (Example: Call external web service to book ticket) and cannot be rolled back.

I created basic workflow test case to test.

Start -> Java Service Task -> End

<code>
<process id="myProcess3" name="My process3" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <serviceTask id="servicetask1" name="Service Task" activiti:async="true" activiti:exclusive="false" activiti:class="TestWrapper">
      <extensionElements>
        <activiti:field name="testField1">
          <activiti:expression>testField1</activiti:expression>
        </activiti:field>
      </extensionElements>
    </serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="endevent1"></sequenceFlow>
  </process>
</code>   

TestWrapper just prints variable
<java>
logger.info("TestWrapper called, time="  +execution.getVariable("time"));
</java>

I am starting 50 threads - each launching this workflow to run concurrently.
I am getting below exception all the time

Increasing job executor thread pool size and database connection pool just delays this exception
Using activiti:exclusive="true" - still this error

<java>
Exception in thread "pool-2-thread-5" org.activiti.engine.ActivitiOptimisticLockingException: MessageEntity[802344] was updated by another transaction concurrently
at org.activiti.engine.impl.db.DbSqlSession$DeletePersistentObjectOperation.execute(DbSqlSession.java:239)
at org.activiti.engine.impl.db.DbSqlSession.flushDeletes(DbSqlSession.java:668)
at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:462)
at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:168)
at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:115)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:70)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:37)
at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
</java>

In my case as task is non transactional there is no way to roll back.

Based on forum messages, I thought this error may occur if multiple process engine (and hence multiple job executors) running and each trying to update the job. For this test, there is only one process engine instance running.

Any help is appreciated.

Thanks

spark2
Champ in-the-making
Champ in-the-making
Update - Using Strong UUID doesn't change the result.

I understand exception will roll back activiti database entries but the main issue is non transactional business logic which cannot be roll back. 

I am using activiti 5.12.x - I couldn't find anything in release notes that address this.
Just wondering if anyone else have this issue.

spark2
Champ in-the-making
Champ in-the-making
On further testing (and adding additional logs in activiti source to print persistent object state - no other changes),
I found everytime Optimistic locking exception is throw, I see exception message: Unable to instantiate class (JavaDelegate)

Below are logs for one of the MessageEntity (I can provide full logs, if required)

2014-06-12 12:35:11,266 pool-2-thread-3             TestWrapper INFO  - TestWrapper called, processInstanceId=849d828b-f24f-11e3-b0ab-081196804620, processDefinitionId=myProcess3:33:840fc167-f24f-11e3-b0ab-081196804620, time variable=8426913569603

2014-06-12 12:35:15,036        Thread-2 org.activiti.engine.impl.jobexecutor.AcquireJobsRunnable WARN  - Optimistic locking exception during job acquisition. If you have multiple job executors running against the same database, this exception means that this thread tried to acquire a job, which already was acquired by another job executor acquisition thread.This is expected behavior in a clustered environment. You can ignore this message if you indeed have multiple job executor acquisition threads running against the same database. Exception message: MessageEntity[84a4d5d3-f24f-11e3-b0ab-081196804620], OBJECT STATE: {exceptionMessage=couldn't instantiate class TestWrapper, lockExpirationTime=Thu Jun 12 12:40:14 EDT 2014, lockOwner=d369623d-184a-4465-93a1-05f82183ed79, exceptionByteArrayId=878dc4eb-f24f-11e3-841d-0021283e0734, duedate=null, retries=2} was updated by another transaction concurrently

Exception in thread "pool-2-thread-3" org.activiti.engine.ActivitiOptimisticLockingException: MessageEntity[84a4d5d3-f24f-11e3-b0ab-081196804620], OBJECT STATE: {exceptionMessage=null, lockExpirationTime=Thu Jun 12 12:40:10 EDT 2014, lockOwner=d369623d-184a-4465-93a1-05f82183ed79, duedate=null, retries=3} was updated by another transaction concurrently

—-
Is this error "couldn't instantiate class TestWrapper" — anyway related to optimistic locking exception?

Also why do I see class loading error while this class is definitely called earlier (Logs above - see time stamp)

Thanks

jbarrez
Star Contributor
Star Contributor
> Is this error "couldn't instantiate class TestWrapper" — anyway related to optimistic locking exception?

No, it is not.

Do you have TestWrapper like that on your classpath (no packages?

It doesnt make sense. Could you zip up your test project so we can try it out?