cancel
Showing results for 
Search instead for 
Did you mean: 

Exceptions while trying to resume tasks after lengthy jobs

raadhakrishnaa
Champ in-the-making
Champ in-the-making
As a beginner to Activiti,I am struggling to get my Usecase addressed.Details as follows
A.Scenario :
My ProcessDefinition constitutes multiple activities(predominantly service tasks),of which many of the activities require heavy IO and hence time-taking.
For a servicetask that corresponds to one such I/O activity,I want the ActivitEngine state to be persisted and resume the next sequence of workflow ,based on a signal received from the external business task

B.My Current Approach
All the descriptions laid here are in reference to the enclosed piece of code below.I have my workFlowDefinition as seen in "MyWorkFlowDefinition.bpmn20.xml" section .The service tasks correspond to execution of methods contained in Java bean "myBean".
I have my current setup working through Spring Integration.So the object "myBean" can carry references to RunTimeService,taskService etc of Activiti. The myBean object then invokes the external business Logic ,passing the reference of executionId,ProcessInstanceId of current executionContext . The external business code,at the end of execution wants to signal the WorkFlowEngine ,that it can resume the workflow with next sequence of tasks of workFlowDefinition.

========================================="MyWorkFlowDefinition.bpmn20.xml"=========================================
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
             targetNamespace="http://activiti.org/bpmn20"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:activiti="http://activiti.org/bpmn">
 
 
  <process id="SequenceExecution">
 
    <startEvent id="start" />
   
    <sequenceFlow id="flow1-step1" sourceRef="start" targetRef="step1" />
    <serviceTask id="step1" activiti:expression="#{myBean.method1(arg1,arg2,arg3,arg4,execution)} " />
   
     <receiveTask id="flow2-step2" name="flow2-step2" />         
    <sequenceFlow id="flow3-step2" sourceRef="flow2-step2" targetRef="step2"/>
   
    <serviceTask id="step2" activiti:expression="#{myBean.clearThePain(execution)} " />
   
      <sequenceFlow id="flow4-step3" sourceRef="step2" targetRef="end" />
    <endEvent id="end" />
  </process>

</definitions>

=============================================Spring Integrated Logic==========================================================================

public class myBean {
//Spring initialized service components like
TaskService taskService;
ManagementService mngService;
RunTimeService runtimeService;

public void method1(String arg1,String arg2,String arg3,String arg4,ActivityExecution execution){

print("Entered method.Proceed for execution …");
//…..invoke external code
String executionId=execution.getId();
String engineProcessId=execution.getProcessInstanceId();
new extBean().executeLogic(this,executionId,engineProcessId);


}

public void clearThePain(){

print("Got the control back to WorkFlowEngine.Executing Final task…");
}

}

=============================================External Logic==========================================================================

public class Extbean{

public Extbean(){}

public void executeLogic(myBean beanObj,String executionId,String processEngineId){
  //// Execute the business logic.
  myBean myBeanObj=beanObj;
 
  mybBeanObj.getRuntimeService().signal(executionId);
  mybBeanObj.getRuntimeService().signal(processEngineId);
  mybBeanObj.getRunTimeService().setVariable(executionId,"Var1","ValueForVar1");
mybBeanObj.getRunTimeService().setVariable(processEngineId,"Var1","ValueForVar1");


}

}
C.Challenges Seen


mybBeanObj.getRuntimeService().signal(executionId);
  mybBeanObj.getRuntimeService().signal(processEngineId);
  mybBeanObj.getRunTimeService().setVariable(executionId,"Var1","ValueForVar1");
mybBeanObj.getRunTimeService().setVariable(processEngineId,"Var1","ValueForVar1");
When I invoke the above code,I see an exception as below

May 30, 2012 12:23:47 PM org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: execution flow1-step1 doesn't exist
        at org.activiti.engine.impl.cmd.SignalCmd.execute(SignalCmd.java:50)
        at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
        at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:42)
        at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
        at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
        at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
        at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
        at org.activiti.engine.impl.RuntimeServiceImpl.signal(RuntimeServiceImpl.java:131)

I also tried to pass the id of the receivetask "flow2-step2" and the exception thrown says

SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: execution flow2-step2 doesn't exist
        at org.activiti.engine.impl.cmd.SignalCmd.execute(SignalCmd.java:50)
        at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
…………….
D.Help Needed on
What am I doing wrong here?What is the ideal way of passing reference of current execution context to the external logic such that the WorkFlowEngine can be signalled and activated from its wait state for further execution.
Is this an ideal usecase that can fulfilled with ExecutionListeners or AsyncContinuation aspects of the documentation.If so,Please provide a sample direction of how it can be done

Can someone please help me or offer me hints to do this correctly.

Thank you,
RK
3 REPLIES 3

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Please (re)format your post next time and use code tags for clearity.

The error is here:

org.activiti.engine.ActivitiException: execution waitServerProvision doesn't exist
Why would there be an execution with an id of 'waitServerProvision'?  (I think you only posted part of the stacktrace, right?)

What am I doing wrong here?
You probably stored some wrong reference somewhere to be used to signal the process.

What is the ideal way of passing reference of current execution context to the external logic such that the WorkFlowEngine can be signalled and activated from its wait state for further execution.
Storing/passing on the right information to be used to signal the process. I usually use a combination of business key and receive task name. But it could also be an execution id. Depends…

raadhakrishnaa
Champ in-the-making
Champ in-the-making
Thank you Ronald for the quick response and also your suggestion on presenting the query in a readable format Smiley Happy  .
I had to modify my actual code with alias names for the functions so that it can be easy interpretation for the readers and I missed one such occurrence( 'waitServer…" ) in the stacktrace I pasted ,which probably confused you.I corrected/edited that in my current post.
I do pass the execution id of the current activitytask 'flow1-step1' and also tried the id of receivetask 'flow2-step2' ,but in either case I am reported that the execution does not exist.

Please clarify me on the following
1.If there is a receive task in the definition flow,would there an entry in any of the tables 'act_ru_job' …etc so that the work engine persists the state until then into the tables and waits for a msg signal on the receive task. I did not find any such traces in mysql db tables in my case.

2.For The Java class that corresponds to Service Task,I tried the Java Class as an implementation of 'JavaDelegate' and also an extension of 'TaskActivityBehavior' as understood from the topic http://forums.activiti.org/en/viewtopic.php?f=6&t=3613&p=14092&hilit=Asynchronous+Task#p14092 . All of them result in the same exception

Can someone please give me further direction or hints on this.

Thank you,
RK

frederikherema1
Star Contributor
Star Contributor
1. A receive task doesn't create any jobs of timers. It just stops the process from flowing (== returning the thread that called startProcessInstance(). You can see this in the ACT_RU_EXECUTION. When you runtimeService.signal() the process, it will start again.

From what I understand, this is what you are trying to reach is the following:
- Start a process from thread A. Since the process is heavy on I/O, you don't want thread A to be blocked by this operation. Rather, you want to return control to the thread and let activiti handle the heavy I/O operation.

The problem is that you're trying to signal an execution from within the same execution. At the time you call "signal()" (in #{myBean.method1…), the process is actually still 'flowing' and not yet ready to receive a signal. Since the process is just started, and hasn't reached a wait-state yet (user task, recieveTask, ..), it's not yet persisted in the DB. This is why you get the "execution not found" exception.

Solution: Use Async continuations http://activiti.org/userguide/index.html#asyncContinuations. Remove the first service-task an signal-task, just use this:

<serviceTask id="step2" activiti:expression="#{myBean.clearThePain(execution)} " activiti:async="true" />
Getting started

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.