10 Replies Latest reply on Jul 26, 2006 10:59 AM by ephemeris-lappis

    [jBPM][3.1.1] Get a timer instance with API

    ephemeris-lappis

      Hello.

      How can i retrieve a timer instance with the API, in particular during an ActionHandler invocation, for example on the "task-create" event for a given task ?

      Is the whole task created when the action is called ?

      I've been trying several methods, among them, the getTimer of the ExecutionContext, but it doesn't seem to work : value is always

      null
      ...

      Another alternative should be a way to express the timer delay (duedate) from the jpdl itself, using some form of EL expression to set the attribute...

      Any idea ?

      Thanks.

        • 1. Re: [jBPM][3.1.1] Get a timer instance with API
          cpob

          This looks like a bug to me.

          I made a change in Timer.java to fix this.

          I inserted a line around line # 75 (in the execute() method):

          executionContext.setTimer( this );


          This sets the execution context's timer properly.

          I have yet to write a JIRA issue for this though.

          • 2. Re: [jBPM][3.1.1] Get a timer instance with API
            cpob

            Sorry, I should have been more specific. My above message is in direct reference to the action handler referenced when the timer is finished and calls its associated handler.

            You should not have any timer reference from a task-create action I would think.

            • 3. Re: [jBPM][3.1.1] Get a timer instance with API
              ephemeris-lappis

              Hello.

              I'm afraid i don't understand your last message...

              Do you mean the event handler for a task should not try to use the timer, perhaps because when the event fires, the timer is not created yet ?

              Coming back to my question : is there a way to set or change the timer delay for a given task, with a calculated value, at the time the task activates ?

              Did you commit your fix ?

              Thanks.

              • 4. Re: [jBPM][3.1.1] Get a timer instance with API
                cpob

                I don't have access to commit to the CVS (nor can I do so from work). I created/commented on a Jira though.

                The issue I talk about, is in the action handler. When you have the executionContext, and do a .getTimer() on it (during a timer action event), it would always return null.

                My fix assigns the timer to the ExecutionContext properly so it is there in the action handler if you need it.

                ephemeris-lappis wrote:
                at the time the task activates

                You mean task.start()? or when the task is created?

                You should be able to, I know we're editing timers during the execution of a timer, but we're doing mass timer updates, so we're using named queries. You should be able to do it through the API.

                • 5. Re: [jBPM][3.1.1] Get a timer instance with API
                  ephemeris-lappis

                  Ok for the fix you did on the JIRA...

                  Now, more details about my needs...

                  After a task terminates, the process decides to follow a transition to a new task. This last one must start initializing a timer that must fire after a given timeout. This timeout must be calculated according to business informations that are provided by the finishing step.

                  Ideally, a script expression directly given in the timer definition in the XML file could be perfect i the value formula is not too complicated. But i suppose that such a solution doesn't exist...

                  The alternative i had tried, was to intercept the task creation event, and change the timer delay. But if i understand what you say, it seems it's not a possible solution...

                  So what should i do ?...

                  Thanks anyway for your help, and any new idea is welcome...

                  • 6. Re: [jBPM][3.1.1] Get a timer instance with API
                    cpob

                    Create an action handler and register it with the task-create.

                    Have that handler create a new timer per whatever rules/data you need (which could be from your database, or an context variable).

                    Code to create a timer: (This is from the CreateTimerAction code - around line 72)

                    Timer timer = new Timer(executionContext.getToken());
                     timer.setName(timerName);
                     timer.setRepeat(repeat);
                     Duration duration = new Duration(dueDate);
                     Date dueDate = businessCalendar.add( new Date(), duration );
                     timer.setDueDate(dueDate);
                     timer.setAction(timerAction);
                     timer.setTransitionName(transitionName);
                     timer.setGraphElement(executionContext.getEventSource());
                     timer.setTaskInstance(executionContext.getTaskInstance());


                    Now, don't forget to create the cancel-timer action to end that timer if you finish the next task within the time limit, or else that timer will keep on ticking even if you finish the task. You can find that code in JpdlXmlReader.java, in the readNodeTimer method (around line 479)

                    All this assumes there isn't a timer already configured on it. This is programmatically creating a NEW timer.

                    • 7. Re: [jBPM][3.1.1] Get a timer instance with API
                      ephemeris-lappis

                      Hello, again !

                      I've tried what you said, and it seems to work, except i have had to add two lines or three to register the created timer with the scheduler service.

                      Now, i think this is not a perfect solution ! First, the process definition file doesn't show that a timer is associated with the task, and the business user needs to know about the java code to manage it. Next, the java code must explicitly use jpdl transition ids that might change in the process definition file with no possible crossed verification.

                      I'm sure a way to configure dynamic timer directly from within the jpdl file should be a better solution, using some scripting form as i've suggested it before.

                      I don't know if somebody could do something for that !...

                      Thanks anyway.

                      • 8. Re: [jBPM][3.1.1] Get a timer instance with API
                        kukeltje

                        hmmm..

                        and the business user needs to know about the java code to manage it


                        Should they? Or should there be an action with a kind of 'uml comment' on it that there is a time created. IMO uml comments on transitions/actions etc would eliminate the need for additional nodes sometimes.

                        Reagding creating things from the jpdl, sometimes it indeed handy, but the combination of actionhandlers (with visible comments) sometimes (often?) are a very flexible solution. I not saying it is the best solution here, but we should watch out for creating a to complex language

                        • 9. Re: [jBPM][3.1.1] Get a timer instance with API
                          biggef

                           

                          "ephemeris-lappis" wrote:
                          I've tried what you said, and it seems to work, except i have had to add two lines or three to register the created timer with the scheduler service.


                          Could you please give us those lines ? It may help some other guys. Thanks.

                          • 10. Re: [jBPM][3.1.1] Get a timer instance with API
                            ephemeris-lappis

                            No problem. The code is :

                            package my.wf.seven;
                            
                            import java.util.Date;
                            
                            import org.jbpm.calendar.BusinessCalendar;
                            import org.jbpm.calendar.Duration;
                            import org.jbpm.graph.def.ActionHandler;
                            import org.jbpm.graph.exe.ExecutionContext;
                            import org.jbpm.scheduler.SchedulerService;
                            import org.jbpm.scheduler.exe.Timer;
                            import org.jbpm.svc.Services;
                            
                            public class TimerInitializationActionHandler implements ActionHandler {
                            
                             public void execute(final ExecutionContext executionContext) throws Exception {
                             System.out.println("... Action for timer : " + executionContext.getTaskInstance());
                             Timer timer = new Timer(executionContext.getToken());
                             timer.setName("MY-TIMER");
                             Duration duration = new Duration("5 seconds");
                             BusinessCalendar businessCalendar = new BusinessCalendar();
                             Date dueDate = businessCalendar.add(new Date(), duration);
                             timer.setDueDate(dueDate);
                             timer.setTransitionName("to_activity-2");
                             timer.setGraphElement(executionContext.getEventSource());
                             timer.setTaskInstance(executionContext.getTaskInstance());
                             SchedulerService schedulerService = (SchedulerService) Services.getCurrentService(Services.SERVICENAME_SCHEDULER);
                             schedulerService.createTimer(timer);
                             System.out.println("... Timer : " + timer);
                             }
                            
                             static private final long serialVersionUID = 701975110762314580L;
                            
                            }


                            If somebody has comments... They are welcome !