1 2 Previous Next 15 Replies Latest reply on Jun 3, 2008 9:27 AM by Alan Nisbet

    ending a process from other token than root token

    Ronald van Kuijk Master

      We thought that it was not possible to end a process from one of the legs of a fork open tasks. By default the process, keeps running, only the specific token is ended. Now I know fork/joins may not contain functionality that go's around/outside the fork/join pair. But shouldn't ending a process not be an exception to this?

      while debugging to see if I could develop a workaround, I learned something....

      changing

      <end-state name="e2" />

      to
      <end-state name="e2" end-complete-process='true' />


      in the end-state 'inside' the fork works as expected.... at least for my simple unit test. I'll make some more extended test and file a jira issue for documenting this...

      Shouldn't this behaviour be the default btw?

        • 1. Re: ending a process from other token than root token
          Tom Baeyens Master

           

          "kukeltje" wrote:
          Shouldn't this behaviour be the default btw?


          that is a tricky one. for jPDL 4 we could review this choice. but i'm leaning towards keeping as is. if you show a diagram with a fork and an end-state in one of the branches, I would guess that a majority assumes the rest of the process will not be cancelled.

          introducing this was related to auto-completion. i believe that was triggered by vanderaalst patterns. a process should finish when there is nothing left to do. there is some logic that each time a token ends, it checks if there is some parent token still active. if not, the process instance is ended.

          • 2. Re: ending a process from other token than root token
            Joram Barrez Master

            I've also discovered the "end-complete-process" attribute by accident a few months ago while strolling through the source code.

            Since then, I've used it for every process I had to implement.
            People do understand that ending the process really means that any operation corresponding with the process is finished too.

            I'm sure there are some use cases in which ending all tokens is not needed, but I can't figure out one right away.

            So, as kukeltje stated, this behaviour feels more as a default for me, too.

            • 3. Re: ending a process from other token than root token
              Ronald van Kuijk Master

               

              I would guess that a majority assumes the rest of the process will not be cancelled.

              Well, then the two of my collegues that used jBPM and myself belong to a minority (which bny itself is cool, since I hate being part of a majority)

              there is some logic that each time a token ends, it checks if there is some parent token still active.

              Correct, that is the behaviour, which would not be a real problem if there also was e.g. the option to cancel certain tokens/tasks with a tag in e.g. the end node, or in many other places. BPMN has some notion/notation for this.


              • 4. Re: ending a process from other token than root token
                Tom Baeyens Master

                ok. With Joram joining the camp of changing the default, that makes 2 against 1 :-)

                Let's change the default in jPDL 4.

                • 5. Re: ending a process from other token than root token
                  Tom Baeyens Master

                  i checked it and http://wiki.jboss.org/wiki/JbpmJpdl4 already has the default already to process instance.

                  • 6. Re: ending a process from other token than root token
                    Joram Barrez Master

                    Nice!

                    Ideally, a fork/join combo should always be used, but I've seen my share of processes in which this wasn't feasable.

                    I've checked it with some folks at work and all of them agreed that reaching the end-state means the end of the process and the end of doing operations on that process.

                    So I believe the choice for JPDL 4 is well made.

                    • 8. Re: ending a process from other token than root token
                      Alan Nisbet Newbie

                      Hi,

                      First time poster here. The behaviour you have been discussing is exactly what I require. However when I try to use the "end-complete-process" attribute in the end-state I get the exception

                      org.jbpm.jpdl.JpdlException: [[ERROR] line 127: cvc-complex-type.3.2.2: Attribute 'end-complete-process' is not allowed to appear in element 'end-state'
                      


                      <end-state name="Set-up Failed - ISAM ID" end-complete-process='true' />


                      I'm using JBPM 3.2.2, Is this a version thing? I must be doing something silly here!

                      Cheers

                      • 9. Re: ending a process from other token than root token
                        Tom Baeyens Master

                        probably an oversight in the xsd. can you verify that ?

                        • 10. Re: ending a process from other token than root token
                          Alan Nisbet Newbie

                           

                          probably an oversight in the xsd. can you verify that ?


                          Was that directed at me Tom?

                          I have had a look at the jpdl-3.2.xsd in the jbpm-jpdl.jar shipped with the jbpm-jpdl-suite-3.2.2 release and indeed there is no mention of this attribute in the schema.

                          How do I get a more up-to-date schema?

                          Cheers

                          • 11. Re: ending a process from other token than root token
                            Tom Baeyens Master

                            quickest way is to contribute a patch in the jira issue i created.

                            http://jira.jboss.com/jira/browse/JBPM-1184

                            if we have to do it, it might be postponed. Thanks for reporting it !

                            • 12. Re: ending a process from other token than root token
                              Alan Nisbet Newbie

                              Hi,

                              I have attached the update schema to the jira issue created by Tom.
                              This fixed the exception I was seeing. However I'm still not seeing the behaviour from the process execution that I would expect.

                              Could someone have a look at my test process definition and see if I'm doing something wrong

                              <?xml version="1.0" encoding="UTF-8"?>
                              
                              <process-definition xmlns="" name="forktest">
                              
                              
                               <start-state name="start">
                               <transition to="doThis1"></transition>
                               </start-state>
                              
                              
                               <node name="doThis1">
                               <transition to="fork1"></transition>
                               </node>
                              
                               <fork name="fork1">
                               <transition to="wait for a" name="a"></transition>
                               <transition to="wait for b" name="b"></transition>
                               </fork>
                              
                               <node name="doThis2">
                               <action class="com.ecebs.sample.action.DoThis2ActionHandler"></action>
                               <transition to="join1" name="success"></transition>
                               <transition to="end - doThis2 failed" name="failure"></transition>
                               </node>
                              
                               <node name="doThis3">
                               <action class="com.ecebs.sample.action.DoThis2ActionHandler"></action>
                               <transition to="join1" name="success"></transition>
                               <transition to="end - doThis3 failed" name="failure"></transition>
                               </node>
                              
                               <join name="join1">
                               <transition to="wait state"></transition>
                               </join>
                              
                               <state name="wait for a">
                               <transition to="doThis2"></transition>
                               </state>
                              
                               <state name="wait for b">
                               <transition to="doThis3"></transition>
                               </state>
                              
                               <state name="wait state">
                               <transition to="end"></transition>
                               </state>
                              
                              
                               <end-state name="end" />
                               <end-state name="end - doThis2 failed" end-complete-process='true'/>
                               <end-state name="end - doThis3 failed" end-complete-process='true'/>
                              
                              
                              </process-definition>


                              I set in the ContextInstance a variable that I use to define success or failure, i.e. if success then I call

                              ctx.leaveNode("success")


                              from my action handler, if it fails then I calll same method passing in failure.

                              I still dont see the process completing at the expected end-state which leads me to believe I'm doing something wrong, either in my process definition or my test code

                              test code is


                              @Test
                               public void testFork() {
                               if (log.isDebugEnabled()) {
                               log.debug("inside testFork()");
                               }
                              
                               // Create an instance of the process definition.
                               ProcessInstance instance = new ProcessInstance(processDefinition);
                               debugState("new ProcessInstance()", instance);
                               log.debug("ProcessId is " + instance.getId());
                              
                               // Signal to Start Process
                               log.info("Signaling: Start");
                               signal(instance, null);
                               debugState("1. Start", instance);
                              
                               ContextInstance ctxInst = instance.getContextInstance();
                               ctxInst.setVariable("status", "failure");
                              
                               // Signal: Waiting for a
                               log.info("Signaling: Waiting for a");
                               signal(instance, "a");
                               debugState("2. signal(instance, \"wait for a\")", instance);
                              
                               ctxInst.setVariable("status", "success");
                              
                               // Signal: Waiting for a
                               log.info("Signaling: Waiting for b");
                               signal(instance, "b");
                               debugState("3. signal(instance, \"wait for b\")", instance);
                              
                               // Signal: Waiting for a
                               log.info("Signaling: to exit wait");
                               signal(instance, null);
                               debugState("3. signal(instance, \"null\")", instance);
                              
                               Assert.assertEquals(processDefinition.getNode("end - doThis2 failed"), instance.getRootToken().getNode());
                               //Assert.assertEquals(processDefinition.getNode("end"), instance.getRootToken().getNode());
                               }
                              
                               private void debugState(String action, ProcessInstance instance) {
                               log.info("**************************************************");
                               log.info("just performed action: " + action);
                               log.info("root token node: " + instance.getRootToken().getNode());
                               log.info("root token active children: "
                               + instance.getRootToken().getActiveChildren());
                               log.info("**************************************************");
                               }
                              
                               private void signal(ProcessInstance instance, String childKey) {
                               if (log.isDebugEnabled()) {
                               log.debug("inside signal(instance, childKey = " + childKey + ")");
                               }
                              
                               Token rootToken = instance.getRootToken();
                               if (rootToken.hasActiveChildren()) {
                               Map<?, ?> children = rootToken.getActiveChildren();
                               if (children.containsKey(childKey)) {
                               Token childToken = (Token) children.get(childKey);
                               childToken.signal();
                               } else {
                               // TODO handle this
                               String msg = "Root Token does not contain, " + childKey;
                               log.debug(msg);
                               throw new RuntimeException(msg);
                               }
                               } else {
                               rootToken.signal();
                               }
                               }
                              


                              Help is much appreciated!

                              • 13. Re: ending a process from other token than root token
                                Alan Nisbet Newbie

                                Hi

                                Interestingly in my debug, I see that node-entered is the required end state however execution of the process does not finish at this point!

                                10:47:20,613 [main] INFO ForkTest : Signaling: Waiting for a
                                10:47:20,613 [main] DEBUG ForkTest : inside signal(instance, childKey = a)
                                10:47:20,613 [main] DEBUG GraphElement : event 'before-signal' on 'State(wait for a)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'node-leave' on 'State(wait for a)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'transition' on 'Transition(148aa23)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'node-enter' on 'Node(doThis2)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : executing action 'Action(a46701)'
                                10:47:20,613 [main] DEBUG DoThis2ActionHandler : Calling leaveNode("failure")
                                10:47:20,613 [main] DEBUG GraphElement : event 'node-leave' on 'Node(doThis2)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'transition' on 'Transition(failure)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'node-enter' on 'EndState(end - doThis2 failed)' for 'Token(/a)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'process-end' on 'ProcessDefinition(forktest)' for 'Token(/)'
                                10:47:20,613 [main] DEBUG GraphElement : event 'after-signal' on 'State(wait for a)' for 'Token(/a)'
                                10:47:20,613 [main] INFO ForkTest : **************************************************
                                10:47:20,613 [main] INFO ForkTest : just performed action: 2. signal(instance, "wait for a")
                                10:47:20,613 [main] INFO ForkTest : root token node: Fork(fork1)
                                10:47:20,613 [main] INFO ForkTest : root token active children: {}
                                10:47:20,613 [main] INFO ForkTest : **************************************************
                                


                                • 14. Re: ending a process from other token than root token
                                  Ronald van Kuijk Master

                                  Nizzy,

                                  Could you make a new topic in the user forum?

                                  1 2 Previous Next