We are looking for a way to support rescheduling a running timer in Flowable through a standard BPMN mechanism which doesn’t require exposing timers in our API and ran across the following approach in TIBCO.
We’ve put a prototype together of this functionality in Flowable that introduces custom extensions on the signal event to support this behavior. Is there any interest in this support being contributed back to Flowable?
I can certainly see use cases for this, nice feature. So I’m definitely interested seeing your prototype!
Looking at the BPMN you linked to, it does look like a ‘shortcut’ for a non-interrupting boundary signal event that goes to a custom bit of logic (that fetches the timer job and changes the duedate). As our mantra always has been to introduce shortcuts for things we support, ideally the logic could be written in such a way that the standard BPMN approach also works (probably a JavaDelegate that accepts the id of the boundary event and then calls the rescheduling logic is enough).
I haven’t forgotten about this prototype. My colleague and I are just getting back to this and are still working through some scoping issues in which we are trying to decide what timers should be allowed to be rescheduled (or stopped) from the delegate. This seems important especially in the case of multi-instance subprocesses. I hope to have a prototype for you to take a look at in the next couple of days. We are hoping that we will be able to get this functionality merged in before version 6 is released.
Thanks for the PR.
I was thinking, would it be a good idea to add the functionality to change the timer definition of a job to the RuntimeService and maybe also on a lower level to the ManagementService?
So with a call to the RuntimeService rescheduleTimerJob(String processInstanceId, String activityId, String timerValue), you could do a lookup of the timer job like you did in the service task implementation. It would also be nice to have support for changing a timer definition for a start event or for the timer definition in the process definition. And this can be done with the DynamicBpmnService maybe. Having a service task explicitly to reschedule the timer job would then not be necessary, as a developer can implement their own service task implementation by invoking the RuntimeService method.
WDYT?
We could certainly go that route. However, from my perspective it would be nice if there was a standard way to model a process definition in flowable to support rescheduling a timer without having to implement a custom service task for something that is (or at least seems like) a common use case.
In either case I think exposing the rescheduling functionality in a flowable public API such as the management and/or runtime service makes sense as well.
Sure rescheduling a start event timer could be supported as well. However, I guess I don’t see a need there as much since the process definition could be modified and redeployed since the timer only impacts when future processes will be started.
FWIW, I’m not sure I think using a service task to reschedule the timer is the right approach to take. It’s a bit different than the TIBCO example I referenced in my earlier post. I almost would prefer the ability to add a listener to a timer that could be triggered by some kind of event when it should be rescheduled. In our proprietary workflow software we were able to reschedule a timer when the data object that was associated with the timer was updated. We are trying to move away from this approach to something that uses BPMN constructs to reschedule without having to expose timers to our clients via our REST API.
Yes, it would be good to support the rescheduling functionality from BPMN as well. But when it’s implemented in the RuntimeService/ManagementService it makes it a lot easier to add it there as well. A service task could work, but it does look like a heavy weight solution for this. Adding an additional attribute to the timer event definition where you can specify a reschedule timer event name/logical key would work I think. So something like:
The question then is how this reschedule event can be triggered other than via the API. Do we need a reschedule throw event construct you think? It would be nice to allow a static timer definition to be changed as well, in addition to re-evaluating the timer expression. So you would need to be able to pass a new value in as well.
If a reschedule throw event is used will we also need a reschedule catch event? For the boundary timer event case, the reschedule catch event could be attached to the same element (user task, subprocess) as the timer and then invoke the ‘listener’ to reschedule the timer. The reschedule catch event could also provide the ability to specify an expression which could provide the value to change the timer definition (whether its static or not).
For the intermediate timer event case, I think the reschedule catch event might have to accept the id of the intermediate catching event that defines the timer.
Based on 10.4.1 of the BPMN spec, there are different strategies for forwarding a trigger to catching events. The propagation strategy, which ‘is forwarded from the location where the event has been thrown to the innermost enclosing scope instance which has an attached event being able to catch the trigger’, should make it possible to support rescheduling a timer defined in a multi-instance subprocess. Otherwise, I think the reschedule throwing event will trigger all reschedule catching events in each multi-instance subprocess.
We are still considering whether or not we should just expose timers in our REST API since it has the benefit of allowing a timer to be rescheduled without having to model the definition with ‘reschedule’ behavior. Regardless of our decision we still need public API support in flowable to reschedule a job. I can start to look at that.
I created the following pull request which adds support for rescheduling a timer job using the management service. The management service seemed like the best place to add this functionality since it already contained other timer job
methods such as deleteTimerJob.
It’s possible (in theory), that a user task has multiple timer boundary events. When using an additional reschedule catch event you would also need to specify which timer event should be rescheduled. Catch events should be independent of each other to my opinion. So that’s why my proposal was to add an additional attribute to the timer event definition and make it specific to the timer event.
I think if we expose the reschedule of timers in the API, this is already a good entry point for all use cases. It can be modeled in a BPMN process (with some custom code) and you can invoke it via the Java or REST API. If we see interest in the community to be able to model the reschedule event without custom coding, we can always look into it and add it then.