12 Replies Latest reply on Sep 27, 2011 5:00 AM by Miljenko Norsic

    jPBM 5.1, persistent processes get finished without regard to session

    Miljenko Norsic Newbie

      Hi,

       

      I've made a small sample app that stores knowledge session into a H2 database, based on jBPM user guide.

       

      {code}

      PoolingDataSource ds = new PoolingDataSource();

      ds.setUniqueName("jdbc/BitronixJTADataSource");

      ds.setClassName("org.h2.jdbcx.JdbcDataSource");

      ds.setMaxPoolSize(3);

      ds.setAllowLocalTransactions(true);

      ds.getDriverProperties().put("user", "sa");

      ds.getDriverProperties().put("password", "");

      ds.getDriverProperties().put("URL", "jdbc:h2:tcp://localhost/~/test");

      ds.init();

       

      EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");

       

      // load up the knowledge base

      KnowledgeBase kbase = readKnowledgeBase();

      Environment env = KnowledgeBaseFactory.newEnvironment();

      env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

      env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());

       

      Integer sessionId = null;

      if (args != null && args.length == 1) {

      sessionId = Integer.valueOf(args[0]);

      }

      StatefulKnowledgeSession ksession = null;

      if (sessionId == null) {

      // new session

      ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);

      } else {

      // load existing session from database

      ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, null, env);

      }

        // start the transaction

      UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");

      ut.begin();

       

        // start 5 new process instances

      ksession.startProcess("com.sample.bpmn.hello");

      ksession.startProcess("com.sample.bpmn.hello");

      ksession.startProcess("com.sample.bpmn.hello");

      ksession.startProcess("com.sample.bpmn.hello");

      ksession.startProcess("com.sample.bpmn.hello");

      ksession.dispose();

      ut.commit();

      {code}

       

      For each knowledge session, 5 processes are created, and that process waits for a signal (it is not completed).

       

      I have another application that loads knowledge session from database (by using ID that was provided upon knowledge session generation), and that spawns a signal:

      {code}

      ksession.signalEvent("Signal", null);

      {code}

       

      When signal is sent, it effectively runs all process instances into completion, and that is OK.

       

      But when I have for example more stateful sessions persisted, and each has its own set of processes, calling {code}ksession.signalEvent("Signal", null);{code} runs processes from all sessions into completion, not only the processes that belong to that particular session.

       

      Another thing I've spotted: when I load knowledge session from database, method {code}ksession.getProcessInstances(){code} returns empty list.

      That is weird because at the same time method {code}ksession.getProcessInstance(1){code} correctly loads process instance from database.

       

      Thanks,

      Miljenko

        • 1. Re: jPBM 5.1, persistent processes get finished without regard to session
          Miljenko Norsic Newbie

          I forgot to mention that when I target event to a specific process instance (e.g. ksession.signalEvent("Signal", null, 1);), that process instance runs to completion (and is deleted from PROCESSINSTANCEINFO database table), and other processes continue to exist.

           

          From the behavior I've seen it looks like process instances do exist regardless of their parent knowledge session, which is weird as process instances are created on session object....

           

          Thanks,

          Miljenko

          • 2. Re: jPBM 5.1, persistent processes get finished without regard to session
            Miljenko Norsic Newbie

            Hi,

             

            a little bit of digging shows that calling signalEvent() method on a persistent stateful knowledge session effectively selects all signals from EVENTTYPES table:

             

            select processins0_.InstanceId as col_0_0_ from ProcessInstanceInfo processins0_ where ? in (select eventtypes1_.element from EventTypes eventtypes1_ where processins0_.InstanceId=eventtypes1_.InstanceId)

             

            And based on that information, process-related information is returned from PROCESSINSTANCEINFO. That's not correct, as this query should return only processes that belong to that particular knowledge session, and this query returns all processes that register this event.

             

            I think it would be enough to add session id into event types and use this constraint to fetch only processes that belong to that particular knowledge session.

            What do you think?

            • 3. Re: jPBM 5.1, persistent processes get finished without regard to session
              Miljenko Norsic Newbie

              Hi,

               

              I have made a small application to compare persistent and non-persistent processes and event signaling, and it it is obvious that they do not have the same behaviour, even if used on the same code.

               

              Please see attached Eclipse project (you have to add reference to BTM and H2 database driver to make it work, and run "ant start.h2" to run H2 database instance if you use pre-conifigured jBPM5 demo).

              In non-persistent scenario (ProcessTestNonPersistent), calling signalEvent on ksession correctly sends signal to process instances for that particular ksession.

              At the same time, persistent scenario (ProcessTestPersistent) fails down with a NullPointerException:

               

              java.lang.NullPointerException

              at org.jbpm.process.instance.impl.ProcessInstanceImpl.setProcess(ProcessInstanceImpl.java:61)

              at org.jbpm.marshalling.impl.AbstractProcessInstanceMarshaller.readProcessInstance(AbstractProcessInstanceMarshaller.java:380)

              at org.jbpm.persistence.processinstance.ProcessInstanceInfo.getProcessInstance(ProcessInstanceInfo.java:133)

              at org.jbpm.persistence.processinstance.JPAProcessInstanceManager.getProcessInstance(JPAProcessInstanceManager.java:64)

               

              I think both scenarios should behave the same way, regardless of applied persistence strategy.

               

              Thanks,

              Miljenko

              • 4. Re: jPBM 5.1, persistent processes get finished without regard to session
                Miljenko Norsic Newbie

                Hi jBPM gurus,

                 

                I'd like to know is this is a bug that I've reported? I was expecting that both persistent and non-persistent processes behave the same way, and this particular persistent scenario throws an exception.

                Do you want me to file a Jira issue for that?

                 

                Thanks,

                Miljenko

                • 5. Re: jPBM 5.1, persistent processes get finished without regard to session
                  Miljenko Norsic Newbie

                  Hi,

                   

                  I've seen that somebody has already raised a JIRA issue for that (https://issues.jboss.org/browse/JBPM-3240) in the previous thread: http://

                  community.jboss.org/thread/166536

                   

                   

                  Thanks,

                  Miljenko

                  • 6. Re: jPBM 5.1, persistent processes get finished without regard to session
                    Maciej Swiderski Master

                    Hi Miljenko,

                     

                    I checked the examples you provided. Issue with persistent test is that you reuse environment object for both sessions so once you close the first one it will invalidate the environment so the second one can't operate on it any more. If you create two separate instance of the environment that will be dedicated to the session your test will work just fine and in my opinion that is exactly same behavior as for the non persistent state.

                     

                    Regarding the topic in general, I think it is the right approach that you can signal processes regardless of its origin session. That is due to processes can be long running (days, weeks, etc) so once you loose session handle they should be still reachable in some ways.

                    But I see your point too, to be able to signal only processes that origin from a particular session. This can be done by providing process instance id to the signal method, as far as I know. Probably not the perfect way of doing it but should work. This could be a subject for more detailed discussion to try to find out if scoping signaling to only one session is of interest to the community.

                     

                    HTH

                    1 of 1 people found this helpful
                    • 7. Re: jPBM 5.1, persistent processes get finished without regard to session
                      Miljenko Norsic Newbie

                      Hi Maciej,

                       

                      thanks for the reply! I've checked your statement about environment, and when I set up two different environments, it works OK.

                      Unfortunately, it is not that obvious what is the right way to do it, especially taking into consideration that persistent examples are scattered around and not included into JUnit tests (if I'll get some time, I'll try to add it into JUnit tests because I think jBPM deserves much more examples to be more widely accepted in community, because lot of us are struggling with rather incomplete set of samples to build our processes).

                       

                      As for the signalling processes, I didn't realized that processes live separately from their knowledge sessions, because:

                      1. process cannot live without its knowledge session (we create a process on a knowledge session, right?)

                      2. session handle and process handle are persisted together. It means that when I reach some safe state point in process, upon its wakeup I'm going to receive a deserialized knowledge session instance and its child process instances

                      3. I can create many process instances on a same session instance

                      4. rules are also first-class citizens in knowledge session, similar to processes, and processes cannot execute without rules (if they use rule tasks).

                       

                      As I see it, process has its parameters only, and the rest is taken from the session. Please correct me if I'm wrong.

                      Therefore it is somehow strange to call signalEvent(eventId, param) on a ksession and as a result all process instances are notified, and not only those that belong to that particular knowledge session.

                       

                      Also, one thing I've spotted and is by my humble opinion not correct, is that when I call

                       

                      processInstance.signalEvent(type, eventData);

                       

                      only that particular process instance is signaled. For example, if this process instance contains a sub-process with that event, signal is not propagated to a child process.

                      So, in general, I think more scoping would allow process creators more freedom in process creation, and avoid ugly workarounds if one wants to build something uncommon.

                       

                      Thanks,

                      Miljenko

                      • 8. Re: jPBM 5.1, persistent processes get finished without regard to session
                        Jordi Alvarez Newbie

                        Hello, just to add a bit of information to this topic, we detected the same problem in a slightly different situation for a previous version of jBPM (in fact Drools Flow 5.1).

                         

                        The situation also leads to a confussion of sessions and processes, and is described here:

                         

                        http://comments.gmane.org/gmane.comp.java.drools.user/26332

                         

                        We make use of state nodes in our processes, and have a part of process information that is stored in drools-facts. So, we need that our processes live in the corresponding session. Additionally, we make extensive use of timers, which forces us to have a blocking mechanism (which we have implemented based on the identifier of the session).

                         

                        So, we need that processes live inside stateful sessions. We opened a JIRA issue related to this problem:

                         

                        https://issues.jboss.org/browse/JBRULES-3108

                         

                        In the meantime, we have patched drools flow 5.1 in order to have processes attached to stateful sessions (as explained in previous links).

                         

                        greetings,

                        Jordi Alvarez

                        • 9. Re: jPBM 5.1, persistent processes get finished without regard to session
                          Maciej Swiderski Master

                          Jordi, Miljenko, this was exactly what I meant by having a more detailed discussion

                           

                          In my opinion it all comes down to the requirement you have for a particular case. I can see that both of you have similar situations to deal with but I can find number of examples where the default behavior (signal all process instances regardless of the session) can be beneficial. For instance, bank would like to notify all customers that are currently in loan process that terms and conditions of the loan has changed, so if every customer that is tring to get a loan, has started a process and by that mean has its own session to controll the process system would need to find all sessions and then signal it one by one which would not be so nice.

                           

                          But as already could be seen the other side of that case is also quite common. Question is on what level shat that be configured? And if variable scopes are not useful here? I mean perhaps by inserting process variables instead of facts would make sense or not? It could be acceptable if only the process is going to use that piece of data.

                          Cheers

                          • 10. Re: jPBM 5.1, persistent processes get finished without regard to session
                            Miljenko Norsic Newbie

                            Maciej, Jordi,

                            thanks for the discussion.

                            Personally, I think we need a freedom to do both things, because it is obvious that both scenarios are common.

                            My point is that calling

                            ksession.signalEvent(type, eventData);
                            

                             

                            looks as one is trying to signal all process instances in a given knowledge session, but not in *all* knowledge sessions.

                            It would be nicer to have something like this:

                             

                            ksession.signalEvent(type, eventData) - signals all processes in a given knowledge session

                            ksession.signalEvent(type, eventData, processInstanceId) - signals all processes in a given knowledge session

                            ksession.signalEvent(type, eventData, Collection<Long> processInstanceIds) - signals all processes with a given Id in a given knowledge session

                            ksession.signalEvent(type, eventData, long processInstanceId) - signals process with a given id in a given knowledge session

                            processInstance.signalEvent(type, eventData) - signals a particular process instance (the same as previous call)

                            StatefulKnowledgeSession.signalEvent(type, eventData) - signals *all* processes that use this event type

                             

                            And of course, persistency model should be altered based on the API to reflect the changes.

                             

                            BTW, Jordi, can you ask you to share part of your process definition regarding wait states? I'm curious to see an alternative way of doing it by using a fact....

                            I have a situation where I have to implement a lot of "waiting nodes" that are going to decide whether to continue with processing, based on a fact that is going to be asserted every day (in some batch processing, for example).

                            Right now I've developed two solutions:

                            1. custom work item node waiting for the right data to come - fact is part of my work item, and I don't think it will work as work item handlers are not persisted

                            2. calling signalEvent() to wake up waiting node to continue - I'm not happy with this solution as I have to have a number of intermediate catch events scattered through my process

                             

                            Is there a better way to wake up process? Did anyone created a custom work item handler that is registered to respond to signalEvent?

                             

                            Thanks,

                            Miljenko

                            • 11. Re: jPBM 5.1, persistent processes get finished without regard to session
                              Miljenko Norsic Newbie

                              Just to make things a little bit clearer, I'd like to have my process definition as clear as can be and wrap signalling into a custom work item handlers, similar to following image:

                               

                              sample.png

                               

                              Thanks for all advices in advance,

                              Miljenko

                              • 12. Re: jPBM 5.1, persistent processes get finished without regard to session
                                Miljenko Norsic Newbie

                                Hi All,

                                 

                                sorry for the spam, but I'm a jBPM newbie and using it in my project just seems the right way to do it

                                I have spotted another thing that might be useful, and it is used in JUnit tests, particularly in BPMN2-EventBasedSplit3, where a condition node is used to test fact presence in a ksession. But I don't see a support in Eclipse tooling to create such a node. Can I use this paradigm to create my waiting subprocesses?

                                 

                                Thanks,

                                --Miljenko