Remember that setting 'duedate=' on the task or timer can take an interval like '1 business day', so as long as you always have a set interval from the time of task creation, you can simply use the attribute and be fine.
If a set interval is too simple for your needs, you should be able to create an ActionHandler class that is executed on the task-create event. Here your own code should be able to do whatever calculation is necessary and set the task/timer due dates programatically after they have been created.
If your calculation uses process instance variables, you can, of course, specify which ones in your action config...
<task ...> <event type='task-create'> <action class='com.me.myDueDateCalculatorActionHandler'> <varName1>someVariableName</varName1> </action> </event> <timer .../> </task>
I will try to use a custom action to set the timer value.
I've been looking for a way to retrieve the timer in my current state from the executionContext of a custom action, but i've not found any ! Could you please give me lead ?
Another question : in the action code, if the timer timeout is changed, should i explicitly try to save it, using a jbpm context, or will this be done in the current persistence session ?
More questions !
I've changed my test code that used a state node with a task-node just as in your example.
Now, it seems the timer fires twice : my timer action writes a message on system out twice. But it seems the transition from the timer task is done only once.
The full jpdl is at the end of my message...
What goes wrong ?
<?xml version="1.0"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jbpm.org:jpdl-3.1 http://jbpm.org/jpdl-3.1.xsd" name="MY-PROCESS-NUMBER-SIX"> <start-state name="start-of-job"> <transition name="to_activity-1" to="activity-1" /> </start-state> <task-node name="activity-1"> <task name="task_activity-1"> <event type="task-create"> <action class="my.wf.six.TimerInitializationActionHandler" /> </event> <timer name="timer_activity-1" duedate="5 seconds" transition="to_activity-2"> <script> <expression> <![CDATA[ System.out.println("*** TIMER FIRED !!!!!!!"); ]]> </expression> </script> </timer> </task> <transition name="to_activity-3(1)" to="activity-3" /> <transition name="to_activity-2" to="activity-2" /> </task-node> <state name="activity-2"> <event type="node-enter"> <script> <expression> <![CDATA[ System.out.println("*** ENTERING : " + node); ]]> </expression> </script> </event> <transition name="to_activity-3(2)" to="activity-3" /> </state> <state name="activity-3"> <transition name="to_end-of-job" to="end-of-job" /> </state> <end-state name="end-of-job" /> </process-definition>
It has been my experience that any changes made in an ActionHandler to objects retrieved from the ExecutionContext will be persisted without explicitly calling save.
The ExecutionContext at least has a getTimer() method, though I've never used it. If for some reason that method doesn't help, you can always retrieve an existing timer directly with a Hibernate query.
Remember that if you create a timer from scratch in the ActionHandler, then you don't need to configure another timer in your process definition XML.
I don't see anything wrong with your definition, but I can't see what you're doing inside TimerInitializationActionHandler.
Indeed, the ExecutionContext has a getTimer method, but it seems it always returns
null. Has it has no javadoc, i'm not sure this is the good way to retrieve the timer of a task. Perhaps it just works when you use it from a timer action...
I'd prefer use only the jBPM API, and avoid use direct access to the data as you suggest. I've been looking for some method that enumerate the nodes. At this time i've not found anyone, but i will look again. If somebody has an idea...
For the timer reaction, it should not directly depends on what the program does or not. In my case, the java code just sleeps some seconds to let the timer fire, what it does, but twice. I have the same problem with or without the action handler in the jpdl. In my case, the action is just a print... I have a very similar jpdl with a timer in a state node instead of a task node, and it just fires once...
More ideas ?...
Thanks anyway for your help !