How to dynamically change timer value at runtime in BPM Suite / RHPAM ?

Solution Verified - Updated -

Environment

  • Red Hat JBoss Business Process Management Suite (BPM Suite)
    • 6
  • Red Hat Process Automation Manager
    • 7

Issue

  • There is a process which contains a timer modeled as a boundary event attached to a human task. An wrong value (i.e. 30days) was set to the timer through process variable and it is already active. Now the time value needs to be adjusted (i.e. 90days) before the current value becomes effective.

  • How to change a value set using process variable to a Timer modeled as a boundary event in Runtime?

  • We have a scenario where we need to update the date on a timer once it has been set. The old date needs to be evicted and new date needs to be set.

Resolution

BPM Suite 6.0 and 6.1

In order to achieve that, the timer should be cancelled through the time service and a new one registered. Refers to the attached sample (boundaryTimer.zip), the timer instance (which is in this example is firing after 10s) is cancelled and replaced with another one (firing after 25s instead). The example without the UpgradeCommand would fire after 10s as expected, but after the upgrade would fire after 25s instead.

BPM suite 6.2 and later

Since 6.2.0, UpdateTimerCommand is bundled as a built-in command so using it is recommended. It works for both IntermediateTimer and BoundaryTimer.

// update MyTimer to set 5 seconds delay
ksession.execute(new UpdateTimerCommand(processInstanceId, "MyTimer", 5));

https://github.com/kiegroup/jbpm/blob/6.5.x/jbpm-flow/src/main/java/org/jbpm/process/instance/command/UpdateTimerCommand.java

A sample jbpm64ex035_intermediatetimer_updatetimer.zip is attached.

RHPAM 7

It is possible to Update Timer instance over the REST API:
https://github.com/kiegroup/droolsjbpm-integration/blob/master/kie-server-parent/kie-server-remote/kie-server-client/src/main/java/org/kie/server/client/admin/ProcessAdminServicesClient.java#L45-L49

Explanation of these methods:

A) update timer - by process instance id and timer id - updates timer expiration of active timer. It updates the timer taking into consideration time elapsed since the timer was scheduled. For example: In case timer was initially created with delay of 1 hour and after 30 min it's decided to update it to 2 hours it will then expire in 1,5 hour from the time it was updated. Allows to update
delay - duration after timer expires
period - interval between timer expiration - applicable only for cycle timers
repeat limit - limit the expiration to given number - applicable only for cycle timers

B) update timer relative to current time - by process instance id and timer id - similar to regular update time but the update is relative to the current time - for example: In case timer was initially created with delay of 1 hour and after 30 min it's decided to update it to 2 hours it will then expire in 2 hours from the time it was updated.

C) list timer instances - by process instance id - returns all active timers found for given process instance

Universal approach

It's also possible to design a process in a way, it will allow a dynamic change of the timer. This is probably the safest and prefered approach. Of course, not possible for already deployed process instance.

Attach is such process definition (DynamicTimer.bpmn2.zip) - here is the explanation:

It's modeled in a way that it allows you to change timer value using signal.

At first, process is started with variable timerValue equal to R/PT5s (this means unlimited number of repetitions every 5s). The timer modeled in a process is configured with Timer Cycle attribute equal to expression #{timerValue} - so whatever timerValue variable you'll set, it will be used as a Timer Cycle.

It produced following log:

15:08:51,132 INFO  [stdout] (pool-33-thread-2) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess
15:08:56,133 INFO  [stdout] (pool-33-thread-1) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess
15:09:01,130 INFO  [stdout] (pool-33-thread-3) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess
15:09:06,128 INFO  [stdout] (pool-33-thread-2) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess
15:09:11,128 INFO  [stdout] (pool-33-thread-1) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess

As you can see, the timer is fired every 5s.

Later on, I have send an "udpateTimer" signal, with data equal to this string: "R/PT10s". Output of updateTimer signal is mapped to variable timerValue. So this call changed the interval from 5s to 10s. It produced following logs:

15:09:13,244 INFO  [stdout] (http-127.0.0.1:8080-6) Updating timer, new timer value:R/PT10s
15:09:14,270 INFO  [stdout] (pool-33-thread-2) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess
15:09:24,268 INFO  [stdout] (pool-33-thread-3) Pretending we are starting separate process - in reality, this could be rest task to kie-server, or signal, or reusable subprocess

As you can see - the interval is now 10s.

Attachments

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.