[jboss-jira] [JBoss JIRA] (WFLY-4657) EJB timer blocked after trigger+suspend+activate operations and JDBC storage
Kabir Khan (JIRA)
issues at jboss.org
Wed Dec 6 11:21:22 EST 2017
[ https://issues.jboss.org/browse/WFLY-4657?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Kabir Khan closed WFLY-4657.
----------------------------
> EJB timer blocked after trigger+suspend+activate operations and JDBC storage
> ----------------------------------------------------------------------------
>
> Key: WFLY-4657
> URL: https://issues.jboss.org/browse/WFLY-4657
> Project: WildFly
> Issue Type: Bug
> Components: EJB
> Affects Versions: 10.0.0.Alpha1
> Reporter: Jan Martiska
> Assignee: Stuart Douglas
> Fix For: 10.0.0.Alpha2
>
>
> Scenario:
> - The AS is configured to use a JDBC storage for EJB timers (using the H2 ExampleDS is sufficient for reproduction)
> - There is a persistent calendar timer going off every few seconds
> - The 'trigger' management operation is called on that timer
> - The timer goes off one time extra, as expected
> - The 'suspend' management operation is called on that timer
> - After a few seconds, the 'activate' operation is called on that timer
> - The timer will never go off again (not even by invoking 'trigger' operation)
> The cause:
> - Each time the timer goes off, a new java.util.TimerTask is scheduled to handle the next alarm
> - When the 'trigger' operation is invoked, the TimerServiceImpl computes the timestamp of the next alarm and schedules a new TimerTask
> - The problem is that this new TimerTask overwrites the one currently registered in the TimerServiceImpl, because the TimerServiceImpl assigns TimerTasks to Timers using a map: https://github.com/wildfly/wildfly/blob/10.0.0.Alpha1/ejb3/src/main/java/org/jboss/as/ejb3/timerservice/TimerServiceImpl.java#L905 - the TimerServiceImpl loses the reference to the previously registered TimerTask and doesn't cancel it
> - From now on, each new alarm registers the next TimerTask, but makes TimerServiceImpl forget the previous one
> - After some time, when the 'suspend' operation is called, the TimerServiceImpl cancels its stored TimerTask. However, it doesn't know that there is another scheduled elsewhere
> - The TimerTask goes off during the time when the timer is suspended.
> - DatabaseTimerPersistence checks whether the TimerTask can run and sets the Timer's state to IN_TIMEOUT if yes (https://github.com/wildfly/wildfly/blob/10.0.0.Alpha1/ejb3/src/main/java/org/jboss/as/ejb3/timerservice/persistence/database/DatabaseTimerPersistence.java#L395). However, this is done BEFORE checking whether the timer is suspended. DatabaseTimerPersistence commits this change. Then comes the mentioned check (https://github.com/wildfly/wildfly/blob/10.0.0.Alpha1/ejb3/src/main/java/org/jboss/as/ejb3/timerservice/task/TimerTask.java#L141) and it fails, so the Timer will not go off, but the Timer state remains IN_TIMEOUT forever!
> - With every next invocation, as the timer's state remains IN_TIMEOUT, all invocations are skipped.
--
This message was sent by Atlassian JIRA
(v7.5.0#75005)
More information about the jboss-jira
mailing list