This is a cross post from a github issue: https://github.com/ebryn/backburner.js/issues/86
We are seeing this behavior intermittently:
-
Ember.run.later is called to schedule a future execution
-
Internally, this updates laterTimerExpiresAt to the next future execution timestamp and a browser setTimeout schedules the call and timer id is recored in laterTimer.
-
The computer goes to sleep
-
Computer wakes.
-
Intermittent but causes the bug: the timer never fires.
-
Now, laterTimerExpiresAt and laterTimer hold values that cause this updateLaterTimer to never execute its body, causing future schedule calls to never execute.
function updateLaterTimer(self, executeAt, wait) {
if (!laterTimer || executeAt < laterTimerExpiresAt) {
// we don't enter this block because
// executeAt > laterTimerExpiresAt and laterTimer has a value.
...
// executeAt could also be in the past after a sleep/wake
laterTimerExpiresAt = executeAt;
}
}
Possible fix:
function updateLaterTimer(self, executeAt, wait) {
var now = (+new Date());
if (!laterTimer
|| (executeAt < laterTimerExpiresAt)
|| (laterTimerExpiresAt < now)) { // also check for stale timers
if (laterTimer) {
// immediately trigger any stale timers.
if (laterTimerExpiresAt < now) {
wait = 0;
}
clearTimeout(laterTimer);
}
laterTimer = global.setTimeout(function() {
laterTimer = null;
laterTimerExpiresAt = null;
executeTimers(self);
}, wait);
// base laterTimerExpiresAt on now and wait value
// instead of possibly out of date executeAt
laterTimerExpiresAt = now + wait;
}
}