cancel
Showing results for 
Search instead for 
Did you mean: 

Timer start event not starting all process instances

tushard
Champ in-the-making
Champ in-the-making
Hi,

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:
<bean id="jobExecutor" class="org.activiti.engine.impl.jobexecutor.JobExecutor">
    <property name="lockTimeInMillis" value="2700000"/>
    <property name="corePoolSize" value="15"/>
    <property name="maxPoolSize" value="30"/>
</bean>
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?


Best regards,

Tushar
5 REPLIES 5

frederikherema1
Star Contributor
Star Contributor
If the thead-pool is exhausted, an implementation of the following class is consulted:


/**
* <p>Strategy for handling jobs that were acquired but cannot be
* executed at this point (queue-size exceeded).</p>
*
* @author Daniel Meyer
*/
public interface RejectedJobsHandler {

  public void jobsRejected(JobExecutor jobExecutor, List<String> jobIds); 
 
}

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.

tushard
Champ in-the-making
Champ in-the-making
Hi,

You said that
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.

- Tushar

frederikherema1
Star Contributor
Star Contributor
Yes, by default, it is. You can change this behavior any way you'd like…

tushard
Champ in-the-making
Champ in-the-making
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?

In Activiti 5.10, is it ok if I implement following custom rejected jobs handling policy?  Here, I am asking the jobExecutor to retry the rejected jobs.
public class MyRejectedJobsHandler implements RejectedJobsHandler {
public void jobsRejected(JobExecutor jobExecutor, List<String> jobIds) {
     jobExecutor.executeJobs(jobIds);
}
}

- Tushar

jbarrez
Star Contributor
Star Contributor
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).