Hi,
usertasks have a boolean attribute ‘suspended’ ; mapping to, I guess, column ‘act_ru_task.suspension_state_’ .
My question : Can somebody give some more background on how this is supposed to work, especially in combination with suspending a process instance? Some things I’m pondering on:
if I suspend a process instance, are the usertasks automatically suspended as well?
if I suspend a task, will the API prohibit any more changes to this task (e.g complete a task), or is it our own responsibility to make these checks?
My ‘business reason’ I’m posting this question:
We have usecases where an external trigger (another system) should cause a process instance to be cancelled. So far, so good. But, sometimes, in real life, people make mistakes, or bad communication happens, and several minutes up to a few hours later, they revert the ‘cancellation’ in the other system.
If we immediately cancel a process instance on the first external trigger; we can never undo ’ this cancellation’. So I’m thinking about adding some time-dependant buffer, before actually cancelling the process instance.
But, while such a process instance is, let’s call it ‘pending cancellation’, I want to mask any usertasks from being visible / completeable by end-users (we use our own GUI, not the activiti webapp).
So, would I anger the Flowable spirits if I implement the following: ?
when I receive a ‘pending cancellation’ from the external system, I loop over all usertasks of our process-instance, and for-each update them and set suspended to ‘true’
I then program my GUI to hide suspended tasks (and if needed, to prohibit completing them)
when I receive a ‘undo cancellation’ , loop again, and set set suspended to ‘false’ again for each usertask
when no ‘undo cancellation’ is received, we could then program that after 12 hours, a real ‘cancel process instance’ is performed.
Yes, when a process instance is suspended, all the active user tasks will automatically become suspended. And the API validates that a user task is not suspended before it can be completed. When a user task is suspended and the complete action is invoked, an exception is thrown.
The use case you are describing would work. You don’t need to loop over all user tasks, when suspending a process instance all user tasks will be set to suspended automatically.
Hi Tijs,
thanks already for the quick answer. Suspending the process instance seems the way to go for us, indeed.
Are there any other effects for suspending a process instance, next to suspending usertasks? Admitted, I could test all this myself, but I guess other forum might also be interested.
Some of the typical things that can still ‘cause progress’ in an instance, next to usertasks:
are timers halted (e.g an execution is waiting on a timer catching event) ?
will asynchronuous service tasks be suspended from execution?
can BPMN messages or BPMN signals be sent?
thanks for clarifying, that can help me judge the risk / impact on our process instances in general.
Hi tijs,
when I try to suspend a asynchronous service task job, I have a problem that the process continue to go.
public class TestServiceTask implements JavaDelegate {
...
@Override
public void execute(DelegateExecution execution) {
...
//produce a queue message
runtimeService.suspendProcessInstanceById(execution.getProcessInstanceId());
}
}
I want to produce a queue message and then suspend this asynchronous service task in the TestServiceTask. I active the process when receiver response message.
How can I suspend asynchronous service task jobs?
Use ActivityBehavior instead of JavaDelegate, I have solved this problem that a asynchronous service task job is suspended but the process continue to go. But I have a new problem that TestServiceTask is repeated excution when I active the process, this is not what I expected, because it will produce repetitive queue messages.
Hi,
When I active the process, add code: ((FlowNode) execution.getCurrentFlowElement()).setBehavior(null);
my problem have been resolved. Thanks for Flowable, its awesome!
Hi,
I am trying to suspend the process instance for user interaction to do action like accept or reject the process flow.
public class UserWorkflowTaskListener implements ExecutionListener { @Override
public void notify(DelegateExecution execution) {
runtimeService.suspendProcessInstanceById(execution.getProcessInstanceId());
}
}
but its give me an error
2019-09-23 16:48:01.524 ERROR 26851 — [enerContainer-1] o.f.c.e.impl.interceptor.CommandContext : Error while closing command context
java.lang.NullPointerException: null
at com.rpa.core.process.tasklistener.UserWorkflowTaskListener.notify(UserWorkflowTaskListener.java:75) ~[classes/:na]
at org.flowable.engine.impl.delegate.invocation.ExecutionListenerInvocation.invoke(ExecutionListenerInvocation.java:35) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.delegate.invocation.DelegateInvocation.proceed(DelegateInvocation.java:35) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.delegate.invocation.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:26) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.bpmn.helper.ClassDelegate.notify(ClassDelegate.java:99) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper.executeExecutionListeners(ListenerNotificationHelper.java:79) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.agenda.AbstractOperation.executeExecutionListeners(AbstractOperation.java:78) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.agenda.AbstractOperation.executeExecutionListeners(AbstractOperation.java:69) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.agenda.ContinueProcessOperation.executeSynchronous(ContinueProcessOperation.java:141) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.agenda.ContinueProcessOperation.continueThroughFlowNode(ContinueProcessOperation.java:113) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.agenda.ContinueProcessOperation.continueThroughSequenceFlow(ContinueProcessOperation.java:311) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.agenda.ContinueProcessOperation.run(ContinueProcessOperation.java:79) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:88) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:72) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:56) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:25) ~[flowable-engine-6.4.0.jar:6.4.0]
at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53) ~[flowable-engine-common-6.4.0.jar:6.4.0]
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:71) ~[flowable-engine-common-6.4.0.jar:6.4.0]
at org.flowable.common.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:49) [flowable-spring-common-6.4.0.jar:6.4.0]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) [spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:46) [flowable-spring-common-6.4.0.jar:6.4.0]
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) [flowable-engine-common-6.4.0.jar:6.4.0]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) [flowable-engine-common-6.4.0.jar:6.4.0]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) [flowable-engine-common-6.4.0.jar:6.4.0]
Hey @rg2609 please post new topics instead of writing to an older topic.
The NPE that you have has nothing to do with suspending the task. I don’t know how you have the runtimeService defined in your UserWorkflowTaskListener. If you are autowiring it then you should not use class delegate for your listener. If you use class delegate Flowable will instantiate the class for you, it won’t go via the Spring dependency injection. You could either use a delegate expression or a normal expression to access your bean or access the runtime service via CommandContextUtil.getProcessEngineConfiguration().getRuntimeService().
Cheers,
Filip
P.S. There is no reason for you to crosspost (I saw that you posted on Stackoverflow)