At the moment, jBPM 5 timers are not persistent. (See linked JIRA.) QE considers timer persistence to be a critical requirement for any enterprise-grade BPM solution - furthermore, it is a feature that's missing in comparion to jBPM 3. Timers should be persistent (ie. survive server restarts) and furthermore, it should be ensured that a timer only fires once, no matter how many instances of jBPM there are in a cluster.
Note that timers are persistent. They are saved as part of the session state. Restoring a session from database also restores the timers, so they can fire if necessary. Timers also fire only once, on the session where the timer is registered. The JIRA refers to the fact that the session needs to be active for the timer to fire. If the user disposes the session, the timer will not fire any more. In situations where a long-lived session is used to execute processes, the session will always be alive (and can be restored in case of server restart) and timers will fire as requested. In more complex set-ups, where multiple sessions are used and sessions could be disposed in between, a centralised session could be used to manage the timers when the other sessions are disposed. A solution where sessions can automatically be restored when a timer might need to fire, for example by using quartz to trigger this, is under development in the community but not yet available.
Esteban Aliverti <esteban.aliverti> made a comment on jira JBPM-3170 Another important thing that must to be covered is race conditions caused by timers. If a timer "wakes up" while the process (or any other process in the same session) is being executed, one of the 2 will fail (the process or the timer) because both threads are going to try to modify the DB at the same time. This problem occurs with or without a disposed session.
Esteban Aliverti <esteban.aliverti> made a comment on jira JBPM-3170 Another important thing that must to be covered are race conditions caused by timers. If a timer "wakes up" while the process (or any other process in the same session) is being executed, one of the 2 will fail (the process or the timer) because both threads are going to try to modify the DB at the same time. This problem occurs with or without a disposed session.
Kris Verlaenen <kris.verlaenen> made a comment on jira JBPM-3170 Esteban, When a timer, fires, it sends a signal that is then picked up by the process instance that is waiting for that timer. This signal is sent through the command service, which synchronizes and makes sure multiple threads are not executing simultaneously. Do you have a test case that shows this issue? If so, could you open a new JIRA for this and attach the issue?
Amin Mohammed-Coleman <aminmc> made a comment on jira JBPM-3170 In our case the session is disposed. We have up coming use cases where we need to utilise timers. "In more complex set-ups, where multiple sessions are used and sessions could be disposed in between, a centralised session could be used to manage the timers when the other sessions are disposed." --> Is there a timeframe for when this might be available? or is there any early access to the code? We need to implement timers and I'd rather look a consistent solution so when this becomes available we can remove our copy.
Melih Cetin <cetin.melih> made a comment on jira JBPM-3170 Kris, The explanation you gave on 01/Feb/12 10:33 AM was the case with jBPM5.1. Staring with jBPM5.2 I also observed that timers are not persisted (only the Timer-IDs are persisted). With some debugging, I noticed the following piece of commented code from org.jbpm.marshalling.impl.ProcessMarshallerImpl which may be the reason for this public void writeProcessTimers(MarshallerWriteContext outCtx) throws IOException { outCtx.writersByClass.put( ProcessJobContext.class, new TimerManager.ProcessTimerOutputMarshaller() ); // this is deprecated, will delete soon (mdp) // ObjectOutputStream stream = context.stream; // TimerManager timerManager = ((InternalProcessRuntime) ((InternalWorkingMemory) outCtx.wm).getProcessRuntime()).getTimerManager(); long timerId = timerManager.internalGetTimerId(); outCtx.writeLong( timerId ); // // // need to think on how to fix this // // stream.writeObject( timerManager.getTimerService() ); // // List<TimerInstance> timers = new ArrayList<TimerInstance>( timerManager.getTimers() ); // Collections.sort( timers, // new Comparator<TimerInstance>() { // public int compare(TimerInstance o1, // TimerInstance o2) { // return (int) (o2.getId() - o1.getId()); // } // } ); // for ( TimerInstance timer : timers ) { // stream.writeShort( PersisterEnums.TIMER ); // writeTimer( context, // timer ); // } outCtx.writeShort( PersisterEnums.END ); } Additionally, I noticed that SessionInfo record is not updated upon creation of boundary timers for sub-processes. I hope, this extra bit of information helps to fix this critical issue.
There are no known issues with timers and persistence. Note that a recent refactoring has unified timer persistence across jBPM and Drools (explaining the changes and commented out code), but timers should be persisted as part of the session state. Setting need_info flag, for more detail on what the actual issue is, or whether this issue can be closed.
Kris Verlaenen <kris.verlaenen> updated the status of jira JBPM-3170 to Resolved
Lukas, can I change the status of this issue to CLOSED - NOT_A_BUG?
(In reply to comment #10) > Lukas, can I change the status of this issue to CLOSED - NOT_A_BUG? Sure. Even better, I'll do it for you. (By the way - I think that this used to be an issue in the early days of the release. It must have been fixed somewhere along the road.)