04-13-2011 09:20 AM
04-18-2011 11:08 AM
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).
04-18-2011 01:48 PM
I have a few related questions and performance improvement suggestions:
1) How does the historyService work? Is it performing asyncrhonous writes to the DB or does it block the "main" thread of the process execution? If it does not do any async writes yet, may be it should? BTW, some log4j appenders actually support this mode of operation to offload the busy worker threads in Java(EE) apps.
2) Imagine the situation, where user tasks (or more generically wait states e.g. waiting for async responses from certain external services) do not last very long and are completed in just a few milliseconds. This can be the case, where users are not humans, but other processes and can react very quickly. Right now, AFAIK, Activiti stores the state of the current execution into the DB and then waits. Once user task is completed (or waiting in a waiting state is over), Acitiviti would restore the process state from a DB and continue the execution. My profiler shows that these save/restore actions introduce quite some overhead and DB access contention if uses under heavy load and with many concurrent process instances being executed. Therefore, I was thinking about the following optimization:
Defer the DB writes for saving a state of process instances for a certain configurable amount of time (e.g. 1 second). If after this timeout, the user task (or wait state) are still waiting and not finished yet, flush those writes to the DB and proceed as usual. But if it finished in the meantime, then there is no need to store this state anymore and all related pending writes can be just ignored. And a restore operation just reuses the RAM versions of the process instance state. As a result, it makes Activiti usable under high load (and even for certain kinds of soft-real time apps).
04-19-2011 03:05 AM
I have a few related questions and performance improvement suggestions:
1) How does the historyService work? Is it performing asyncrhonous writes to the DB or does it block the "main" thread of the process execution? If it does not do any async writes yet, may be it should? BTW, some log4j appenders actually support this mode of operation to offload the busy worker threads in Java(EE) apps.
It is not doing async writes. I think one of the reasons is that (at least in our situation) we need them… always… They cannot be lost. So they need to be written to some persistent store in a transaction. Sure something could be implemented that writes them to a local files store (quick) and some other process puts them async in the db. But then you also need some option to still retrieve them if the local storage crashes… etc… much more complicated then it looks at first sight. But if you have other cleaver ideas, let me (us know)2) Imagine the situation, where user tasks (or more generically wait states e.g. waiting for async responses from certain external services) do not last very long and are completed in just a few milliseconds. This can be the case, where users are not humans, but other processes and can react very quickly. Right now, AFAIK, Activiti stores the state of the current execution into the DB and then waits. Once user task is completed (or waiting in a waiting state is over), Acitiviti would restore the process state from a DB and continue the execution. My profiler shows that these save/restore actions introduce quite some overhead and DB access contention if uses under heavy load and with many concurrent process instances being executed. Therefore, I was thinking about the following optimization:
Defer the DB writes for saving a state of process instances for a certain configurable amount of time (e.g. 1 second). If after this timeout, the user task (or wait state) are still waiting and not finished yet, flush those writes to the DB and proceed as usual. But if it finished in the meantime, then there is no need to store this state anymore and all related pending writes can be just ignored. And a restore operation just reuses the RAM versions of the process instance state. As a result, it makes Activiti usable under high load (and even for certain kinds of soft-real time apps).
Isn't this a kind of second level cache? Would (kind of) work for single node systems, but what if there are multiple nodes and other nodes could execute next steps in the process, so yes it might introduce issues unless you use something like teracotta. And wait states including user tasks (at least in our case) last way, way more than one second, so this would not yield much.
If they are short (as in your case, you might choose not to use waitstates and just use service taks so everything is done in one transaction (at least those are the things we take into account when developing a process) . You might need to increase the number of threads/connections though
If they are short (as in your case, you might choose not to use waitstates and just use service taks so everything is done in one transaction (at least those are the things we take into account when developing a process) . You might need to increase the number of threads/connections though
04-20-2011 04:15 AM
04-20-2011 04:35 AM
Not much tie now to go through all the posts - will do at a later point in time (man, you should write books ;-))
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.