cancel
Showing results for 
Search instead for 
Did you mean: 

Long-running service tasks

jsher
Champ in-the-making
Champ in-the-making
Hi,

I would like some advice on best way to implement long-running service tasks in BPMN and Activiti. By long-running I mean tasks which will take more than a second and up to some indeterminate time.

Based on my understanding of how Activiti works (including transaction handling and threading) am I correct in saying that such tasks should not be implemented as synchronous Service Tasks since this would block the engine processing (thread) of the workflow until the blocking invocation returns ?

Rather I suspect it may be best to use a User Task and asynchronously signal completion of the 'long-running' task or alternatively send a message to initiate the task and again asynchronously signal completion of the task. Does this sound reasonable ? Also with these approaches I am guessing that it is straightforward to configure BPMN timer events which fire if the task is not completed in some specified time - something which may not be possible when using blocing Service Tasks.

Thanks
    James
6 REPLIES 6

jsher
Champ in-the-making
Champ in-the-making
Hi again,

Apologies for bumping but I'd be interested in some opinions please. Hopefully I've explained myself ok and it's clear what kind of opinion/confirmation I'm interested in, specifically that it's not a good idea to block a thread in a service task invocation for seconds/minutes/etc

Thanks
    James

jbarrez
Star Contributor
Star Contributor
The Activiti engine has specifically added async continuations to the engine. Mark your service task as async and the thread of the caller will be returned.
The job executor (don't forget to enable it in your config), will pick it up afterwards and continue the work in its own threadpool.

jsher
Champ in-the-making
Champ in-the-making
Many thanks for the reply Joram. If I understand it correctly async continuations are mainly there to provide better control over transaction boundaries and not to provide a pool of threads which are suitable for executing long-running tasks.

I guess that essentially my question is what is best way to handle the situation where I have a task which takes eg. 30 minutes to complete. Is it ok to implement this in a blocking service task, blocking thread (even if this is a JobExecutor thread) for the duration ? Or should this be achieved using an approach which involves async signalling of task completion (like user task or message receiving) ?

Thanks
    James

jbarrez
Star Contributor
Star Contributor
30 minutes sure is a long time! The job executor threadpool could be an option, but if you have many of those long running tasks, I'm worrying the system will not function properly. The job executor threadpool is configurable (but not documented), so you should find the right balance.

The alternative is writing your own queue system: send a message to some queue, do the work somewhere externally and send a message back to a receive task in the process using the execution id. However, this is exactly what the job executor does, so my first take would be to use the job executor.

jugglingcats
Champ in-the-making
Champ in-the-making
Sorry to bump this old thread but the advice in the last post seems to contradict the more recent post here… http://forums.activiti.org/content/modelling-async-user-wait-long-running-service-task.

We have a similar requirement for a long running service task (FTP of large files), and it would be good not to have to complicate the workflow designer's job by including another tech such as Camel, and have them configure receive tasks, etc each time.

The statements in the other thread seem clear: a blocked service task will keep a TX open and eventually the database will time out. Is it fundamental to the engine design for it to work this way, or is this something that might be modified in the future? I agree with the statement above that the job executor gets us most of the way there… it's a slight shame it has this timeout limitation.

Thanks, Alfie.

trademak
Star Contributor
Star Contributor
Frameworks like Camel provide the asynchronous functionality you are looking for by default. So I do think this is the best way to go forward. It doesn't complicate things more than if we would implement the same functionality in Activiti. Re-using functionality from another framework seems to be a more logical approach then implementing it again in Activiti.

Best regards,