12 Replies Latest reply on May 31, 2010 8:18 AM by swiderski.maciej

    [jBPM 4.3] Cancel Job/Timer

    nilspreusker

      Hi,

      I'm trying to find a way to cancel or delete jobs or timers to move a process instance into the state "active-root".

      Here is a more detailed description of what I'm trying to do: I have a state ("wait state") that contains a transition with a timer, which will execute a java activity ("do something"). Now I want to provide an alternative path of execution, in case something goes wrong with the java activity. Since the process instance is in state "inactive scope" (because the job has to be finished before the execution can move on), I'll get an exception when I signal the process instance to move to "another wait state". I suppose, that by deleting or canceling the timer and the associated job, the state of the process instance would be set to "active-root".

       

      I'm aware that "TimerEventTest" in the examples does almost the same things, but it uses an event listener with a timeout. In this case, I can't use a timeout, because the alternative path of execution is also supposed to work if the timer already fired and something went wrong.


      Consider the following process definition:

      cancel-job.png
      =================================
      <?xml version="1.0" encoding="UTF-8"?>

      <process name="cancel-job" xmlns="http://jbpm.org/4.3/jpdl">
           <start g="88,11,48,48" name="start1">
              <transition g="-69,-18" name="to wait state" to="wait state"/>
           </start>
           <state g="65,92,92,52" name="wait state">
              <transition g="-93,-18" name="to do something" to="do something">
                  <timer duedate="20 minutes"/>
              </transition>
              <transition g="272,118:-114,-18" name="to another wait state" to="another wait state"/>
           </state>
           <java class="de.nilspreusker.DoSomething" g="58,218,105,52" method="doSomething" name="do something">
              <transition name="to end1" to="end1" g="-51,-14"/>
           </java>
           <state g="206,218,133,52" name="another wait state">
              <transition name="to end1" to="end1" g="14,-14"/>
           </state>
           <end name="end1" g="167,336,48,48"/>
      </process>
      =================================
      ... and test case:
      =================================
      package yourpackage;

      import org.jbpm.api.ProcessInstance;
      import org.jbpm.test.JbpmTestCase;

      public class CancelTest extends JbpmTestCase {

           String deploymentId;

           protected void setUp() throws Exception {
                super.setUp();

               deploymentId = repositoryService.createDeployment()
                    .addResourceFromClasspath("yourpackage/cancel-job.jpdl.xml")
                    .deploy();
            }

           protected void tearDown() throws Exception {
                repositoryService.deleteDeploymentCascade(deploymentId);
                super.tearDown();
            }

           public void testJavaInstantiate() {
                ProcessInstance processInstance = executionService.startProcessInstanceByKey("cancel_job");
                String pid = processInstance.getId();

                assertTrue(processInstance.isActive("wait state"));
                assertTrue(processInstance.getState().equals(ProcessInstance.STATE_INACTIVE_SCOPE));

               // This throws: "org.jbpm.api.JbpmException: execution[cancel_job.7] is not active: inactive-scope"
               // executionService.signalExecutionById(processInstance.getId(), "another wait state");
            }
      }
      =================================

        • 1. Re: [jBPM 4.3] Cancel Job/Timer
          kukeltje

          Not having a timer puts it in the corect scope. Not sure if cancelling the timer puts it in the correct scope to. Try it...

           

          Cheers,

           

          Ronald

          • 2. Re: [jBPM 4.3] Cancel Job/Timer
            nilspreusker

            I'm afraid my question wasn't clear. I couldn't find an API function to cancel a timer. Maybe someone can give me a pointer as to how to do this (with an internal casting if that should be required).

             

            Cheers, Nils

            • 3. Re: [jBPM 4.3] Cancel Job/Timer
              kukeltje

              Ahh... ok... I looked into this a little, and with some small changes, the timer can be deleted. Still, the state is still wrong and just setting it to something more appropriate looks easy but has a lot of consequences. parent executions, scoping etc...

               

              Look e.g. in the destroyScope method in ExecutionImpl. Best is to file a jira issue for this. But formulate it generic so the implementation could e.g. be that signalling an execution with a timer becomes possible and the timer is deleted or that the timer can be deleted separately and after that the execution can be signalled. I prefer the latter so it could be used more generically.

              • 4. Re: [jBPM 4.3] Cancel Job/Timer
                nilspreusker

                Thanks for you reply Ronald. I've created the JIRA issue: JBPM-2770

                 

                Cheers, Nils

                • 5. Re: [jBPM 4.3] Cancel Job/Timer
                  kafsinkaf

                  Hi,

                   

                  We were having a similar case in a situation where we had a state with repeated timer event. The timer job signals the execution if an external event took place since the previous activation. Signaling was working fine but timer event was still re-scheduled and it was causing an exception to be thrown with a stack dump as follows:

                   

                  2010-05-23 16:12:58,688 ERROR [org.jbpm.pvm.internal.cmd.ExecuteJobCmd] - exception while executing 'timer[40087|2010-05-23 16:12:58,680|timeout]'
                  org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [org.jbpm.pvm.internal.model.ExecutionImpl#40086]
                      at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:447)
                      at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:189)
                      at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:178)
                      at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
                      at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:191)
                      at org.jbpm.pvm.internal.model.ExecutionImpl_$$_javassist_23.getActivity(ExecutionImpl_$$_javassist_23.java)
                      at org.jbpm.pvm.internal.job.TimerImpl.execute(TimerImpl.java:95)
                      ...
                     
                  We have solved the problem with a small change in org.jbpm.pvm.internal.job.TimerImpl.execute method. The modification was (full source code is attached to this posting):

                   

                  31a32
                  > import org.jbpm.pvm.internal.client.ClientExecution;
                  97a99,106
                  >       /* begin fix */
                  >       if (repeat != null) {
                  >           ClientExecution exec = environment.get(DbSession.class).findExecutionById(execution.getId()); //check if the execution is still alive
                  >           if (exec == null) {
                  >               repeat = null;
                  >           }
                  >       }
                  >       /* end fix */

                   

                  If the change is approved by jBPM team then this patch can be applied to org.jbpm.pvm.internal.job.TimerImpl and can also be considered in the handling of JIRA issue: JBPM-2770. This patch does not address JBPM-2770 fully (you can not cancel a timer externally) but allows a workaround where the timer itself can signal the execution and future activations of the repeated timer is cancelled.

                  • 6. Re: [jBPM 4.3] Cancel Job/Timer
                    rebody

                    Hi Melih,

                     

                    I guess your problem is not delete related timer job correctly, while signal a execution.  Could you show us more details about how you signal a execution which is related a timer job?

                    • 7. Re: [jBPM 4.3] Cancel Job/Timer
                      kafsinkaf

                      Hi HuiSheng,


                      The simplified process definition is:

                       

                      <process name="TimerTest" xmlns="http://jbpm.org/4.3/jpdl">
                         <start g="185,63,48,48" name="start">
                            <transition g="-44,-18" name="to task1" to="task1"/>
                         </start>
                         <task g="162,161,92,52" name="task1" candidate-groups="sales-support">
                            <transition g="-43,-18" name="to state" to="state"/>
                         </task>
                         <state g="162,232,92,52" name="state">
                            <on event="timeout">
                            <timer duedate="1 minute" repeat="1 minute"/>
                               <event-listener class="mytest.TimerTest">
                                  <property name="successTransition">
                                     <string value="toTask"/>
                                  </property>
                               </event-listener>
                            </on>
                            <transition g="-44,-18" name="toTask" to="task"/>
                         </state>
                         <task g="162,320,92,52" name="task" candidate-groups="sales-support">
                            <transition g="-42,-18" name="to end1" to="end"/>
                         </task>
                         <end g="183,410,48,48" name="end"/>
                      </process>

                       

                      and the simplified event handler where we signal the execution is:

                       

                      public class TimerTest implements EventListener {
                          static int cnt = 0;
                          private String successTransition;
                         
                          public String getSuccessTransition() {
                              return successTransition;
                          }

                       

                          public void setSuccessTransition(String successTransition) {
                              this.successTransition = successTransition;
                          }

                       

                          public void notify(EventListenerExecution execution) throws Exception {
                              cnt++;
                              if (cnt > 2) {
                                  progress(execution);
                              }
                          }

                       

                          public void progress(EventListenerExecution prmEventListenerExecution) {
                              org.jbpm.api.Configuration.getProcessEngine().getExecutionService().signalExecutionById(prmEventListenerExecution.getId(), successTransition);
                          }

                      }

                      • 8. Re: [jBPM 4.3] Cancel Job/Timer
                        rebody

                        Hi Melih,

                         

                        At this moment, It is really not recommand signaling a execution in the EventListener.   I think it is maybe that there is no way to cancel a timer for a waiting execution.  Seems we should consider about how to deal with it.  And thank you for you patch.

                        • 9. Re: [jBPM 4.3] Cancel Job/Timer
                          kafsinkaf

                          Hi HuiSheng,

                           

                          If it is not recommended to signal an execution in the EventListener then could you please let me know the recommended way of handling the following scenario.

                           

                          We are working with a trading partner and we are putting an asynchronous request to the trading partner via their web service. Completion of the task may take some time for the partner. The way to  check if the task is completed is to make an inquiry again using their  web service in fixed intervals. The current process definition is:

                           

                          1. put an asynchronous request to a trading partner via a web service (done via a java task).
                          2. go to a 'state' and check the completion of task regularly (currently done by a Timer and EventListener).
                            • If the task status is complete, progress the workflow to the next activity (currently done by the EventListener).
                            • If the task does not get completed within say 48 hours, progress the workflow to a manual task for error handling (currently done by the EventListener).

                           

                          How would you suggest us to implement this scenario?

                           

                          Thanks,

                           

                          Melih

                          • 10. Re: [jBPM 4.3] Cancel Job/Timer
                            rebody

                            Hi Melih,

                             

                            Could you let your partner callback process engine after they complete their job?  You could send the executionId as a parameter including the async request message.  And the partner should know how to callback the process after their job.  Then we could put the timer in a transition, and timeout will signal the specified transition and let execution go on running.

                             

                            If the partner cannot callback process engine, then we could use a decisionActivity to verify whether the partner has done their job, yes will continue, no will go back to the stateactivity.

                             

                            But be careful when you chose the second way, because there is bug for this scenario,  please refer https://jira.jboss.org/browse/JBPM-2794.  This bug has been fixed in the jBPM 4.4.

                             

                            In my opinion, I think it is definitely a bug that process won't delete related timer after it was signaled by external system and we should find a way to handle it.

                            • 11. Re: [jBPM 4.3] Cancel Job/Timer
                              rebody

                              Wait a minute, if timer won't be deleted after process signaled, then the first solution won't success.  Hmm, I should go back to do some test.  If I could find some answer, I will post here, Thank you.

                              • 12. Re: [jBPM 4.3] Cancel Job/Timer
                                swiderski.maciej

                                Hi,

                                 

                                please take a look at following thread, perhaps it will suit your needs as well.

                                 

                                https://community.jboss.org/message/541397

                                 

                                HTH

                                Maciej