14 Replies Latest reply on Dec 18, 2012 9:45 AM by franco80

    jBPM 5.1 in a real world web application

    rahzel

      We are writing a prototype based on Java EE 6 (JSF 2.0, EJB 3.1, JPA 2.0). Application Server is JBoss AS 6.1. The customer described his business processes (about 30) in BPMN 2.0. There are many business rules as well and he wants to configure the rules (not the processes) in the running system without developer assistance. We are evaluating jBPM 5.1 and Drools Expert/Guvnor 5.2 for this purpose. After reading the manuals and many threads in this forum and spending some days programming I have some questions. Mainly about the scope and lifecycle of the KnowledgeSession and long running business processes. Most answers you read are like “it depends on the scenario”. So I try to describe our scenario.

      Our target is to develop a business (web) application for an administration department. There are about 100 parallel users. The business processes consists of many nodes (average around 10) including user tasks, business rule tasks, service tasks, gateways and timers. The business use cases respectively the user interface are task centric. For example a process instance is started by a user or within another process execution, the process instance runs in a user task and generates a task which is displayed in a specific task list. Another user logs in, completes the tasks and the process instance proceeds. After that it runs maybe into a business rule task and after that again in a user task generating another type of task. Thus the processes are long running (several days or even weeks).

      Everything has to be persistent. After a failure or maintenance reboot every process instance has to be in the state before the reboot.

       

      KnowledgeSession Scope

      I can’t really determine in which Scope (per request, per user session, per application, per process instance) to instantiate the KnowledgeSession. I have some questions to narrow down the choice:

      Question 1: Is the session thread safe? If not application scope wouldn’t be an option.

      Question 2: What’s about facts (input/output data for business rules)? I it reliable to work with only one session (application scope) which manages many running process instances involving business rule tasks? I fear that’s not the case, because facts are added to the session. Thus the result would be unreliable if multiple parallel rule executions run in one session.

       

      KnowledgeSession persistence

      I don’t know if it is required to load and reuse persisted sessions after a server reboot. The KnowledgeSession and process instances both get persisted. I implemented an example where I have some process instances in a wait state (human task). When I restart the server and create a new session I can complete a human task and the process instance proceeds. Thus it seems that a persisted process instance is independent from a concrete session.

      Question 3: Is there a reason to load and reuse persisted sessions after a server reboot? If yes and if I have more than one session (for example because I use one session per http request) how would I know which session to load concerning a specific wait state? When I complete a task I don’t know which session was active as the process instance hit the wait state.

       

      Timers

      Question 4: Is it true that timers are not persistent? See https://issues.jboss.org/browse/JBPM-3170. Thus I have to use an external timer service if I want to implement long running processes with timers? Any ideas?

       

      Summary

      Question 5: Considering the above topics, what would be the best practice to deal with the KnowledgeSession?

       

      Thanks in advance!

        • 1. Re: jBPM 5.1 in a real world web application
          rahzel

          I would really be happy for an answer or some pointer. I found this issue about thread safety:

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

          Unfortunately it's still open.

           

          Thanks!

          • 2. Re: jBPM 5.1 in a real world web application
            krisverlaenen

            Regarding the scope of the session:  the session itself is threadsafe, and especially when using persistence, we make sure multiple threads are not changing the same data (as this would only result in conflicts anyway).   Depending on the required performance, it might be possible to simply use one session to run all requests.  In this case however, I would recommend using one session per case (where a case is long-lived so could span multiple requests and multiple process instances but typically is about one isolated set of data).  The main reason is that this will prevent data from other unrelated cases to influence your execution, which is especially possible once you start using rule tasks.  So whenever a request comes in, look up the related case id somehow and try to reload the session from the database (or create a new session if this is a new case).

             

            Regarding reloading the sessions, the only thing you should make sure of is that, if you use timers, that the timers are actually re-registered (so this automatically leads to question 4), as timers are part of the session state, and those timers will only trigger if that session is active.  There are a few possible approaches here: (1) use a centralized session to put your timers in, and make sure that session is restored after reboot, so that timers will still trigger on that session, or (2) use some kind of persistent timer trigger (like quartz) that would reactivate the session if a timer would need to trigger (we have some community work on this as an extension of the normal timer service but it's not completely integrated yet).

             

            So I would recommend using a session per case and simply disposing your session once you're done processing the request, and the session will simply be reloaded for the next request for that case.  And registering all timers to a centralized session before disposing the session so that they still get triggered if the session is disposed, and simply restoring that session in case of restart.

             

            Hope this helps,


            Kris

            • 3. Re: jBPM 5.1 in a real world web application
              wwweeii

              I want to know how to  reload a session from the database?

              • 4. Re: jBPM 5.1 in a real world web application
                mariemm

                See: http://docs.jboss.org/jbpm/v5.1/userguide/ch07.html#d0e2745

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

                 

                To recreate session, you need to know sessionId. But what I don't know how to get it in a smart way.

                Is there an good practice how to get sessionId?

                • 5. Re: jBPM 5.1 in a real world web application
                  rahzel

                  Thanks for your answer Kris! I have some questions about your suggestion.

                  When a process is in a wait state (human task), how would I know which session to load on task completion? Should I save the “case”-id in the task? Or better the session-id (id of KnowledgeSession)? Thus I don't have to persist a case-id – session-id mapping? Which field of a task would be appropriate for this and how can I set it dynamically on task creation?


                  About timers: How can I register a timer to this centralized session? And when would be the time to do this (a timer could be anywhere within a process)? What happens if the timer expires when the server isn't running? And what happens if a timer expires/fires in this centralized session? I think the process execution goes on within this centralized session. Thus if there is a rule task executed after the timer, we have the same problem (concurrent session access) again. Thus I have to load the session related to the case? But where and how can I switch process execution from one session to another?

                   

                  The whole solution seems very complicated and error-prone to me. Another concern is about the human task service (we integrate it in-memory with a self-written connector): As I understand so far it uses local transaction and can't be integrated into JPA transactions. This is a show-stopper in a business application. Are there any plans to include JPA support?

                  • 6. Re: jBPM 5.1 in a real world web application
                    rahzel

                    I would really appreciate an answer. Kris, could you or maybe someone else with jBPM experiance help?

                    • 7. Re: jBPM 5.1 in a real world web application
                      rahzel

                      As we are close to the deadline to decide if we are going to use jBPM 5 in our project I ask again for further clarification.

                      Maybe Mauricio (who is very active at the moment) could help?

                      You can ignore the topic "Human task service and transactions" (see post #5) as it is discussed here: http://community.jboss.org/thread/162963

                       

                      But it would be really nice if we could expand the discussion about session scope and timers!

                      • 8. Re: jBPM 5.1 in a real world web application
                        krisverlaenen

                        jBPM5 allows you to define yourself how many sessions you want and the scope of those sessions.  If you want to use more than one session for your application, you should define some kind of session manager that can look up the relevant session.  In general, this means you just create some simple mapping table from some application-specific case id to the session id.  We will be looking at how to do this automatically for you once we support different correlation mechanisms, so you don't have to maintain this mapping manually, but that is not possible yet at the moment.

                         

                        Regarding the timers, the easiest solution is probably just to copy any existing timers to the centralized timer session after executing a command on the session.  Alternatively, you could register a custom timer manager that does not register the timer locally but always registers timers remotely (as well).

                         

                        Kris

                        • 9. Re: jBPM 5.1 in a real world web application
                          ashu_akg21

                          Hi kris,

                                  i read lot of ur blogs n got lot of help in jbpm. actually this thread is not related to my problem but i want ur help so i m posting here.

                           

                          actually m using jbpm5.3 and working on human tasks. bur when i put any rule task after human task its not getting executed. i tried in lot of ways but suggestions was regarding previous version.so can u help me out regarding this issue.i tried

                          1)to restore the session. then file rules

                          2)kcontext.getKnowledgeRuntime().insert(kcontext.getProcessInstance()); previous rule node

                          3)tried to fire all rules in different event

                          and smtimes working

                          but did not find a consistent solution

                          • 10. Re: jBPM 5.1 in a real world web application
                            krishnapitla

                            hi ashutosh,

                             

                            try out this code

                            k

                                  kbuilder.add(ResourceFactory.newClassPathResource(

                            "simplerule.drl"), ResourceType.DRL);

                            in your code where you try to start the process .

                            Sample code pasted below :

                             

                            Hope this helps . Though i am still new to jbpm and drools. So if i have missed something then please pardon me.

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                             

                            package

                             

                            com.sample;

                             

                            import

                             

                            org.drools.KnowledgeBase;

                            import

                             

                            org.drools.builder.KnowledgeBuilder;

                            import

                             

                            org.drools.builder.KnowledgeBuilderFactory;

                            import

                             

                            org.drools.builder.ResourceType;

                            import

                             

                            org.drools.io.ResourceFactory;

                            import

                             

                            org.drools.runtime.StatefulKnowledgeSession;

                             

                            /**

                            * This is a sample file to launch a process.

                            */

                            public

                             

                            class

                            ProcessMain {

                             

                             

                            public static final void main(String[] args) throws

                            Exception {

                             

                            // load up the knowledge base

                            KnowledgeBase kbase = readKnowledgeBase();

                            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

                             

                            // start a new process instance

                            ksession.startProcess(

                            "com.sample.bpmn.hello"

                            );

                            ksession.insert(

                            new

                            Account());

                            ksession.fireAllRules();

                            }

                             

                             

                            private static KnowledgeBase readKnowledgeBase() throws

                            Exception {

                            KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

                            kbuilder.add(ResourceFactory.newClassPathResource(

                            "simplerule.drl"), ResourceType.DRL

                            );

                             

                            kbuilder.add(ResourceFactory.newClassPathResource(

                            "sample.bpmn"), ResourceType.BPMN2

                            );

                             

                            return

                            kbuilder.newKnowledgeBase();

                            }

                             

                            }

                             

                            );
                            • 11. Re: jBPM 5.1 in a real world web application
                              ashu_akg21

                              Hi Kris,

                               

                              We tried this approach of maintaing the mapping table between user reference and session id and reloading the session on completion of the human task. We encountered a strange behavior. When we reload first time, the succeeding script task executes but the rule task which follows it does not execute. On reloading the session the second time, the succeeding script task executes and the following rule task executes twice. This happens consistently [Rule task executing twice on alternate reloads]. Could you please advise?

                               

                              Thanks

                              • 12. Re: jBPM 5.1 in a real world web application
                                ashu_akg21

                                Hi kris,

                                        We have developed a process flow in which we used only single ksession on application start up.the problem is that application is working fine for single user but when it comes to multiple user. then human task user assignment goes wrong. can u please help on this issue

                                • 13. Re: jBPM 5.1 in a real world web application
                                  ashu_akg21

                                  Hi kris,

                                         i have an another  problem.in  which if there are complex rule execution between two human task.then sometimes it Break the flow and second human task does'nt get assined the task. and process gets completed before that.

                                       u can hav a look at our process flow.

                                  • 14. Re: jBPM 5.1 in a real world web application
                                    franco80

                                    Hello Kris,

                                     

                                    "Regarding the timers, the easiest solution is probably just to copy any existing timers to the centralized timer session after executing a command on the session.  Alternatively, you could register a custom timer manager that does not register the timer locally but always registers timers remotely (as well)."

                                     

                                    can You explain a little more what is "the centralized timer session" and how to copy any existing timers to timer session ?

                                     

                                    regards