04-13-2011 09:20 AM
04-13-2011 09:33 AM
PooledDataSource pooledDataSource =
new PooledDataSource(ReflectUtil.getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword );
if (jdbcMaxActiveConnections > 0) {
pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections);
}
if (jdbcMaxIdleConnections > 0) {
pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections);
}
if (jdbcMaxCheckoutTime > 0) {
pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime);
}
if (jdbcMaxWaitTime > 0) {
pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime);
}
04-13-2011 09:41 AM
By default (not using spring datasource and not having altered configuration), the ibatis connection-pool size is fixed to 10. Did you alter the pool size? If not, locked threads makes perfect since the thead puttrough are trottled by this limit…
Limit can be altered using property 'jdbcMaxActiveConnections' on activiti cfg.
Relevant code responsible for create pooled dataSource (ProcessEngineCOnfigurationImpl).
PooledDataSource pooledDataSource =
new PooledDataSource(ReflectUtil.getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword );
if (jdbcMaxActiveConnections > 0) {
pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections);
}
if (jdbcMaxIdleConnections > 0) {
pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections);
}
if (jdbcMaxCheckoutTime > 0) {
pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime);
}
if (jdbcMaxWaitTime > 0) {
pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime);
}
If this isn't the issue, consider using DBCP-datasource pool, which is a proven pooling lib, instead of the built-in (myBatis).
04-13-2011 11:05 AM
Thanks! This is an interesting hint. How can I replace the myBatis datasource pool via the DBCP pool? Can it be done purely via a configuration or in the client code? Or do I need to alter the Activiti code in the ProcessEngineCOnfigurationImpl?
04-14-2011 04:00 AM
04-14-2011 04:42 AM
Interesting findings. The synchronized block you see if to allocate a block of ids for the current Activiti engine. In normal use cases, the fetching of this id-block is infrequent since the block is big enought.
However in your use case of course, the ids are quickly gone. Maybe we would need to make the id-block size configurable.
Keep us tuned about your findings with the DBCP datasource!
In normal use cases, the fetching of this id-block is infrequent since the block is big enought.
However in your use case of course, the ids are quickly gone. Maybe we would need to make the id-block size configurable.
// delete all the tasks
CommandContext commandContext = Context.getCommandContext();
List<TaskEntity> tasks = (List) new TaskQueryImpl(commandContext)
.executionId(id)
.list();
for (TaskEntity task : tasks) {
if (replacedBy!=null) {
task.setExecution(replacedBy);
} else {
task.delete(TaskEntity.DELETE_REASON_DELETED);
}
}
List<Job> jobs = new JobQueryImpl(commandContext)
.executionId(id)
.list();
for (Job job: jobs) {
if (replacedBy!=null) {
((JobEntity)job).setExecution((ExecutionEntity) replacedBy);
} else {
((JobEntity)job).delete();
}
}
04-15-2011 04:04 AM
Indeed. And it is already configurable, though not described in the docs yet.
It can be configured like this:
<property name="idBlockSize" value="10000" />
As you can see, it always tries to get the lists of tasks and jobs and then remove them if required. The interesting part of this observation is that I do not use any tasks and jobs at all, but still pay the price for them! I think it should be optimized somehow…
May be it is possible for the Activiti engine to remember that a certain process instance never created any tasks or jobs? If such a boolen flag would exist, one could avoid issuing such useless DB queries. What do you think?
Another place, where useless DB queries are produced is in VariableScopeImpl, which uses DB always to initialize vars from a DB. It creates a lot of DB traffic. And it does it even on process instance creation, where it is known that no variables could be stored in the DB for this instance already. Again, here it could be optimized in a similar way, i.e. if it is a creation of a process instance and no varaibles were defined yet, there is no need to ask the DB for their values.
04-15-2011 05:12 AM
Indeed. And it is already configurable, though not described in the docs yet.
It can be configured like this:
<property name="idBlockSize" value="10000" />
Wow great findings! I had already forgotten about that property!
As you can see, it always tries to get the lists of tasks and jobs and then remove them if required. The interesting part of this observation is that I do not use any tasks and jobs at all, but still pay the price for them! I think it should be optimized somehow…
May be it is possible for the Activiti engine to remember that a certain process instance never created any tasks or jobs? If such a boolen flag would exist, one could avoid issuing such useless DB queries. What do you think?
Another place, where useless DB queries are produced is in VariableScopeImpl, which uses DB always to initialize vars from a DB. It creates a lot of DB traffic. And it does it even on process instance creation, where it is known that no variables could be stored in the DB for this instance already. Again, here it could be optimized in a similar way, i.e. if it is a creation of a process instance and no varaibles were defined yet, there is no need to ask the DB for their values.
Yes- I came to the same conclusions a few months ago when I did some profiling.
I believe they can be optimized somehow (eg by keeping a boolean if jobs are created for example).
The stuff you've found is really good stuff to put into a blog (with cool charts ;-), do you have any plans to do such a thing?
I believe they can be optimized somehow (eg by keeping a boolean if jobs are created for example).I'm just wondering if this approach would lead to any problems in the cluster setup. I don't know if it is possible at all, but what would happen if other nodes may potentially add tasks/jobs to the process instance running on the current node. If this is possible, then it is difficult to avoid quering the DB. But even in this case, may be some sort of indications (in the process description or in startup configuraton parameters) can be introduced that this process instance will not get new tasks or jobs from other nodes. More over, there is already a flag for disabling job scheduler, IIRC. If this one is disabled (which is a rather radical step ;-), then there can be no jobs or tasks in the DB anyway, or? So, no need to check the DB for them anyway.
04-18-2011 03:12 AM
Is it possible to re-use the services (runtimeService, historyService, etc) with the pure PVM-API based processes? Or is it tightly coupled to the BPMN implementation on top of the PVM? How hard would it be to extend them to support domain-specific custom workflow languages other than BPMN? Would it be a minor or a very big change?
04-18-2011 07:01 AM
Tom is currently working on refactoring the persistence (because it's a mess at some places). But I doubt that the issue you describe will be fixed soon - as our focus is currently not around persistence. However, if a big customers pops up with this problem, then it will be fixed soon 😉
Is it possible to re-use the services (runtimeService, historyService, etc) with the pure PVM-API based processes? Or is it tightly coupled to the BPMN implementation on top of the PVM? How hard would it be to extend them to support domain-specific custom workflow languages other than BPMN? Would it be a minor or a very big change?
The services are tightly coupled to BPMN. It is better to use the PVM API as-is. Do note that the PVM API is quite low-level compared to the services.
What do you mean with domain-specific stuff? Or better: why would you want it (now that BPMN is a industrty-adopted standard)?
You could always do stuff like we do with KickStart, where we offer a very simple UI that allows to place some tasks sequentially or parallel, which is then translated to BPMN using JAXB.
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.