is there a way to pause a timer? We want the timers only to run while worktime, so if a user task is escalating a mail after 4 hours it should not be escalated on weekends, so when working hours are defined from monday to friday 8am to 5pm and a task is advised on thursday 3pm it should be timer should fire on friday at 10am.
short answer is yes - but… You will need some code to compute when the timer should activate based on knowledge of current day of week and time etc. Hence rather than setting a static duration at design/model time, you will probably want to set the timer at runtime.
To do this, in your model you can set the due date/time as an expression, and at run time, place some code somewhere in the process to compute when the timer should expire and set the value as a process variable which the expression in your model resolves to…
Considering that I already have a mechanism/strategy to obtain the working hours and compute the moment when timer should be fired, how should I be able to do what you suggested? Is it possible to calculate the timer value already considering these working hours when the process is started?
The thread Best way to “recalculate” a timer does also provide a considerable strategy but the best solution would be to perform the original time calculation already considering this (and others) limitations we currently have.
Is there any variation point or configuration in Camunda which allows me to, for instance, change the class which executes timer calculations? Would it be possible to intercept timer calculation to add these extra requirements?
Let me elaborate a little on how the timer works behind the scenes which may help you with your question.
To start with, the BPMN intent of a timer should be interpreted as the timer transition will not occur before the timer due date. Often the timer construct is interpreted more like a realtime operating system, ie the timer will interrupt at precisely the due date. This is not the case.
Hence behind the scenes, the engine creates a job in the job table with a due date set to the duedate of the timer. Thus the job will remain dormant in the job table. When the system time reaches the duedate, then the job then becomes a candidate for acquisition by the job executor. Hence only when the job executor acquires the job and begins the transition will the timer construct be effected. In the interim, if the process context removes the timer, eg its a task boundary timer however the task is complete, the timer job will be removed from the job table and thus will never be run.
Hence for your use case, consider calaculating the due date taking into consideration weekends, holidays etc. Then set the timer to this due date. The engine will then take care of the rest.
You mentioned that in my case it would be good to:
consider calaculating the due date taking into consideration weekends, holidays etc. Then set the timer to this due date
How can I do that? I mean, is there any way to change the class which executes timer calculations? Would it be possible to intercept timer calculation to add these extra requirements? Or would I need to add a listener in my Java code (like a @ProcessApplication or an execution listener) and change the value which was originally calculated?
Changing how it is calculated would surely be great, but I can also change it afterwards. It is just unclear to me how this may be done.
How can I do that? I mean, is there any way to change the class which executes timer calculations? Would it be possible to intercept timer calculation to add these extra requirements?
You have to calculate the due date yourself. There is no class to calculate due date. The way a timer works is its nothing more than a duedate in the job table.
To calculate yourself, you could use say a script task to calculate the duedate based on weekends, holidays etc and set the value to a process variable. Then in your task where you use the timer boundary event, use an expression in the timer process model to use this process variable at runtime…
We would like the system to update the timers automatically, without forcing the user to enter expressions.
I mean, user could should still be able to enter the date as desired (e.g. P10D) and the system would then update this period to respect working hours (e.g. set to 12 days if there is a weekend in this time interval).
In this scenario, I believe we should use listeners to observe timer event occurrences and act accordingly on each event to recalculate the due date accordingly, right?
My first option would be to use Camunda BPM Reactor to link the BPMN with the listener at runtime, as it would allow us to use listeners without modifying the XML file and also eliminate the need of manually setting execution listeners in the Modeler while designing the workflow.
Do you see any other (easier or not) option?
I have taken a look at Process Application Event Listeners but as they are a single listener for all events in a process application I believe this can quickly become a bottleneck and hence is not a very good solution at this moment.
if a user task is escalating a mail after 4 hours it should not be escalated on weekends, so when working hours are defined from monday to friday 8am to 5pm and a task is advised on thursday 3pm it should be timer should fire on friday at 10am.
So you have a business rule with a constant that certain tasks should be managed within 4 working hours.
Hence in your process model, assuming you use a boundary event on a user task to ‘escalate somehow’, I would configure the timer model with an expression which will look for a process variable called escalate.
Have a look at my example in this thread. Here I use an input mapping on the task to generate the timer date. It uses some script to calculate the date…
Just to mention that I am not the original poster, but someone in a pretty similar situation.
I have seen the solution you propose but doing it like this would be a kind of “no go” for us as it would require manual intervention of the person configuring the workflow.
We need a way to automate the calculation taking this responsibility out of the workflow designer, to make sure that it would be consistent through multiple workflows which need to make use of that.
That is why I thought of event listeners, especially through Camunda BPM Reactor to keep XML and Java files as decoupled as possible. I hope it is enough to fulfill this complexity layer, otherwise we will need to rethink how to address this solution.
As I could see, to implement such changes using a BPMN Parse Listener I would need to evaluate the timer expression, discover how much the due date should be shifted and adapt the original BPMN attribute to match this date. Is it correct?
I think that adopting an approach that modifies the original due date instead of interfering in the calculation (such as Process Application Event Listeners, as I mentioned in a previous post) would be easier to control and simpler to implement. It would possibly give us room for future enhancements and functtionalities without needing to implement too much code.
We will proceed with Process Application Listeners in a first phase, potentially replacing them with event-driven approach (through BPM Reactor) if we have time for that.
Thank you very much for all the help. It was certainly very productive and enlightened me a lot!