cancel
Showing results for 
Search instead for 
Did you mean: 

Rewind process

mandas
Champ in-the-making
Champ in-the-making
Dear all,

In our processes, we 've had service tasks with long running transactions. To satisfy this requirement we are sending a JMS message to a queue, and the receiving side signals back the process to proceed. Then it was proposed for a super-user to be able to processes with failed JMS messages and retry the faulty task manually. Our intention was not to modify the flow by adding to it monitoring logic (decision point, has error questions and transitions), so we started the quest of finding a way to rewind a process and then suspend it. Afterwards, the super user will search for suspended processes, will resume them, and the JMS message will be resent. Finally, I 've wrote a small code sample which actually does that thing, although it has very serious limitations and cannot be used in all cases. However, it's a start to share, hoping that someone can push it a little bit further.

So we 've created an implementation of ActivityBehavior which follows :


public class JavaTask extends TaskActivityBehavior {
   
   private static final Logger LOGGER = LoggerFactory.getLogger(JavaTask.class);
   
   @Override
   public void execute(ActivityExecution execution) throws Exception {
      LOGGER.info("Execution: " + execution.getId());
   }
   
   @Override
   public void signal(ActivityExecution execution, String signalName,
         Object signalData) throws Exception {
      if ("notOk".equals(execution.getVariables().get("status"))) {
         LOGGER.info("Suspend process: " + execution.getProcessInstanceId());
         PvmTransition pvmTransition = execution.getActivity().getIncomingTransitions().get(0);
         execution.take(pvmTransition);
          execution.getEngineServices().getRuntimeService().suspendProcessInstanceById(execution.getProcessInstanceId());
      } else {
         leave(execution);
      }
   }
}


The deal is that execute() method send creates and sends a JMS message to some queue. The message consumer then call signal() method by also passing a "status" variable. If there are no errors task, task leaves the execution and instructs the process to proceed. If there are errors, we take the incoming transitions and instruct execution to take() it and, finally, we suspend the process. If we then call runtimeService.activateProcessInstanceById(), activiti re-executes execute() method.

Cheers,
Dimitris
1 REPLY 1

mandas
Champ in-the-making
Champ in-the-making
Limitations include :

- Should not work when service task is multi-instance, or inside a parallel scope
- End event listeners will be executed in either case.