5 Replies Latest reply on Sep 30, 2010 9:53 AM by mwohlf

    Signal a wait state and suspend related running subprocesses

    festano1
      Hi All,
      I'm trying to realize a complex use case with Jbpm 4, and I'm lookin for some advises and answers.
      My requisites are to implements some kind of "phases" inside a business process (which models an authorization issuing system
      for a governative trade organization) that can be "modular" and pluggable to the basis of some normative & legal factors.
      I've move to the use of sub-processes in order to implement this, using a dynamic el expression to decide in runtime what process definition of
      instantiate as sub-process, via parameterizing the jpdl sub-process' key attribute.
      So the structure is composed by a main process, that groups these phases, and many other subprocesses which can can be
      authored by external system and business designers.
      Another requisite is that in one phase (es: when an integration request is started) the main process is paused,
      a timer is started (the pause cannot be longer than a business value, and users must be notified if the suspension is reaching it's limit),
      and then resumed.
      For authoring sub-process I don't find seamless to design for any subprocess some kind of a "suspension" state
      (this would be always present, and redundant), so I'm thinking to enforce the suspension state at the level of the main process:

      Hi All,

       

      I'm trying to realize a complex use case with Jbpm 4, and I'm lookin for some advises and answers.

      My requisites are to implements some kind of "phases" inside a business process (which models an authorization issuing system for a governative trade organization) that must be "modular" and pluggable to the basis of some normative & legal factors.

       

      I've move to the use of sub-processes in order to implement this, using a dynamic el expression to decide in runtime what process definition of  instantiate as sub-process, via parameterizing the jpdl sub-process' key attribute.

       

      So the structure is composed by a main process, that groups these phases, and many other subprocesses which can can be

      authored by external system and business designers.

       

      Another requisite is that in one phase (es: when an integration request is started) the main process is paused,

      a timer is started (the pause cannot be longer than a business value, and users must be notified if the suspension is reaching it's limit),

      and then resumed.

      For authoring sub-process I don't find seamless to design for any subprocess some kind of a "suspension" state

      (this would be always present, and redundant), so I'm thinking to enforce the suspension state at the level of the main process:

       

      process.jpg

      I cannot use the execution suspension of the main process, because of the timer's requisite (execution "suspended" state, also suspend timers and notifications),and I cannot end the sub-process because formally, at the end of the "wait" period it must progress where the sub-process was left.
      The problem is that when signaling the main execution to the "Suspend" state, there is a running sub-process instance that invalidate the operation:
       
      ### EXCEPTION ###########################################
      10:42:32,067 INF | [DefaultCommandService] exception while executing command org.jbpm.pvm.internal.cmd.SignalCmd@3ce40
      org.jbpm.api.JbpmException: execution[MainProcess.50026] has running subprocess: execution[SubProcessRequisitesEvaluation.340002] in state inactive-scope
           at org.jbpm.pvm.internal.model.ExecutionImpl.checkActive(ExecutionImpl.java:1090)
           at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:427)
           at org.jbpm.pvm.internal.cmd.SignalCmd.execute(SignalCmd.java:61)
           at org.jbpm.pvm.internal.cmd.SignalCmd.execute(SignalCmd.java:35)
           at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
           at org.jbpm.pvm.internal.tx.SpringCommandCallback.doInTransaction(SpringCommandCallback.java:45)
           at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
           at org.jbpm.pvm.internal.tx.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:49)
           at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
           at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
           at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
           at org.jbpm.pvm.internal.svc.ExecutionServiceImpl.signalExecutionById(ExecutionServiceImpl.java:93)
           
           
      
      
      I've tried to suspend the sub-process activity execution and resume the main-process activity that maps the sub-process execution (the one in "inactive-scope" state) but it have no effect:

      ...
       
      ExecutionImpl execution = (ExecutionImpl) executionService.findExecutionById(processId);
      logger.info( "MAIN-PROCESS STATE= " + processId + " " + execution.getState() );
      if(execution.getSubProcessInstance() != null){
       logger.info( "SUB_PROCESS STATE= " + execution.getSubProcessInstance().getId() + " " +
       execution.getSubProcessInstance().getState() );
       
       if(Execution.STATE_INACTIVE_SCOPE.equalsIgnoreCase(execution.getSubProcessInstance().getState())){
       
       ExecutionImpl state = execution.getSubProcessInstance().findActiveExecutionIn(activeState);
       state.suspend();
       execution.getSubProcessInstance().suspend();
       logger.info( "SUB_PROCESS STATE= " + execution.getSubProcessInstance().getId() + " " +
       execution.getSubProcessInstance().getState() );
       logger.info( "SUB_PROCESS ACTIVITY STATE " + state + " " + state.getState() );
       execution.resume();
       logger.info( "MAIN-PROCESS STATE " + execution + " " + execution.getState() );
       }
      }
       
      executionService.signalExecutionById(processId, transitionName, variables);
      

      this is the log:
      INFO  ProcessServiceBean - Active state: EVALUATION
      INFO  ProcessServiceBean - MAIN-PROCESS STATE= MainProcess.50026 active-root
      INFO  ProcessServiceBean - SUB_PROCESS STATE= SubProcessRequisitesEvaluation.340002 inactive-scope
      INFO  ProcessServiceBean - SUB_PROCESS STATE= SubProcessRequisitesEvaluation.340002 suspended
      INFO  ProcessServiceBean - SUB_PROCESS ACTIVITY STATE= execution[SubProcessRequisitesEvaluation.340002.TaxCompliance.340005] suspended
      INFO  ProcessServiceBean - MAIN-PROCESS STATE execution[MainProcess.50026] active-root
      ### EXCEPTION ###########################################
      12:05:39,201 INF | [DefaultCommandService] exception while executing command org.jbpm.pvm.internal.cmd.SignalCmd@ebd0be
      org.jbpm.api.JbpmException: execution[MainProcess.50026] has running subprocess: execution[SubProcessRequisitesEvaluation.340002] in state suspended
            at org.jbpm.pvm.internal.model.ExecutionImpl.checkActive(ExecutionImpl.java:1090)
            at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:427)
            at org.jbpm.pvm.internal.cmd.SignalCmd.execute(SignalCmd.java:61)
            at org.jbpm.pvm.internal.cmd.SignalCmd.execute(SignalCmd.java:35)
      So, I'm wondering if the behaviour of Jbpm is wrong or if it's supposed to work in this way (namely: "cannot signal parent execution if subprocess are suspended"),  or BTW if there is a common way to implement this set of requisites.
      thank you in advance for any help you can give me!
        • 1. Re: Signal a wait state and suspend related running subprocesses
          mwohlf

          Hi Stefano,

           

          this is from the userguide:

          If an execution is locked, methods that change the execution will      throw a PvmException and the message will reference the actual locking state. [...]

          An execution implementation will be locked:

          • When it is ended
          • When it is suspended
          • During asynchronous continuations

          The behaviour you describe seems to be intended.

           

          Maybe what you can try to model your usecase is not suspend the process instance or it's sub processes but move to a wait state with an escalation trigger that will fire when the "suspend" time is over. This way the process is not locked.

          • 2. Re: Signal a wait state and suspend related running subprocesses
            festano1

            Thank you for answering, Michael

            Michael Wohlfart ha scritto:

            An execution implementation will be locked:

            • When it is ended
            • When it is suspended
            • During asynchronous continuations

            The behaviour you describe seems to be intended.

             

            Yes, it's true, but no way to resume the activity on "inactive-scope" and then signal the main instance?

            My problem is that I cannot signal the main process, either if sub-process is "active-root" or "suspended", etc:

             

             

            INFO  ProcessServiceBean - SUB_PROCESS STATE: SubProcessRequisitesEvaluation.340002 active-root

            ### EXCEPTION ###########################################

            12:00:32,886 INF | DefaultCommandService exception while executing command org.jbpm.pvm.internal.cmd.SignalCmd@34e1d5

            org.jbpm.api.JbpmException: execution[MainProcess.50026] has running subprocess: execution[SubProcessRequisitesEvaluation.340002] in state active-root

             

             

             

            So "root execution" cannot be changed whatever state  are their relative "sub-executions"!

             

            You talk about a "wait state", but my suspension is acting like a wait state, and i have provided a timer to fire after a timeout, to "resume" process-execution, the problem is to move the whole workflow instance to that state.

            For now I cannot achieve this if sub-process is running, and the solution cannot be to force ending because the sub-process will be locked anyway.

             

            I have completely freedom for implemention  but my stand points are:

             

            1. use sub-processes & choose the definition in runtime;
            2. enforce the suspension in the root-process;
            • 3. Re: Signal a wait state and suspend related running subprocesses
              mwohlf

              Stefano,

              this is from the JavaDoc of the suspend() method:

               

              suspends this execution and all it's child executions.  Human tasks 
              of a suspended execution shouldn't show up in people's task list and 
              timers of suspended executions shouldn't fire.
              

               

              please feel free to ignore my advice ;-) use a wait state

              • 4. Re: Signal a wait state and suspend related running subprocesses
                festano1

                OK, but for me is desiderable to suspend execution of the SUB-PROCESS: what I need is to transition the root-process to a "SUSPEND" state (please, see the image at the begin of the original post).

                 

                Perhaps If execution suspension is not the solution this is not a big problem for me (this reasoning was born because the pvm forbid me to signal the main process that contains the wait state, so i was trying to suspend the sub-process and see what would happen! ).

                 

                Your idea is somewhat vague for me, maybe I don't understand the concept of wait state as you intend it, but: if every signal in the main-process execution, outside the sub-process nodes  will cause an exception (until the sub-process instance is ended, of course , how we can "move to a wait state"? you intend a fork before entering any sub-process node?

                • 5. Re: Signal a wait state and suspend related running subprocesses
                  mwohlf

                  Hmm, I am not exactly sure how to model your usecase, I just got the impression that you were abusing suspend(). From my understanding suspend() shouldn't be used in "normal" process modeling and your usecase sounded more like you wanted some sort of escalation or reminder feature. As far as I know suspend() puts the whole workflow on hold and no timer and signaling will work until you resume().

                  I see your point that starting a subprocess and moving the main process to a wait state is also not possible, sorry I don't have any good idea how to solve that problem right now.