Timer start event not starting all process instances

I would like to know what happens if a timer start event tries to start a process instance when the number of job executor threads specified by the corePoolSize are exhausted. I observed that in such a case, the timer start event failed to start a process instance. I now describe my experiment in detail.

I Created a workflow with timer start event configured as R20/PT1S. The workflow has a single service task that sleeps for 1 minute in the execute method, then wakes up and prints the current timestamp. The jobExecutor settings in the activiti.cfg.xml are as follows:

When I deployed the workflow, I observed that 15 process instances were created within first 15 seconds. However, remaining five instances were not started even after the 15 instances previously started finished executing.

I retried this experiment by configuring the timer start event configured as R20/PT10S. This time, I observed that all 20 instances were successfully started. It can be seen that by the end of the 150 sec, two of the 15 process instances started initially complete their execution. So, next two process instances (16 and 17) were started. By 170 sec, a few other previously started process instances finished executing, so the remaining three process instances (18, 19, and 20) too were started.

Is this the expected behavior of the activiti engine or am I missing something?

By default (CallerRunsRejectedJobsHandler), the calling thread is used to run the job that should have been run by the pool. In most cases, this is the job-aquisition-thread. So any subsequent jobs that need to be executed (while the aquire-jobs thread is busy executing the job) WON'T be executed or added to the pool until the aquisition-thread is freed up again.

As this is sometimes not required behavior, you can implement your custom strategy and plug in in using the ProcessEngineConfiguration.

By default (CallerRunsRejectedJobsHandler), the calling thread is used to run the job that should have been run by the pool. In most cases, this is the job-aquisition-thread.

Does this mean that when the thread pool is exhausted, the job-acquisition-thread is forced to execute a job and therefore, any further jobs are not added to the pool until the aquisition-thread is freed up again.

RejectedJobsHandler and CallerRunsRejectedJobsHandler are part of Activiti 5.10, however, we are using Activiti 5.8 in our project. Inspection of the executeJobs method of the JobExecutor shows that RejectedExecutionException handling is not implemented in Activiti 5.8. Can I implement rejected jobs handler in Activiti 5.8 or is it better to upgrade to Activiti 5.10?

It's always good to upgrade to the latest version of Activiti. We're working very hard to make it better with every release ;-)

I guess the policy might work, but if the jobs were rejected because of an overload, you're just making the problem worse …A more elegant solution would be to put them on a waiting queue and retry a bit later on.

Or, just use the CallerRunsRejectedJobsHandler. That one will definitly execute the job, using the current thread (which might slow down the job execution … which is a good thing if the system is saturated).