What happens to setTimeout when the computer goes to sleep?

JavascriptSettimeout

Javascript Problem Overview


In a modern web browser, suppose I do a setTimeout for 10 minutes (at 12:00), and 5 minutes later put the computer to sleep, what should happen when the system wakes up again? What happens if it wakes up before the 10 minutes are up (at 12:09) or much later (at 16:00)?

The reason I'm asking is because I'd like to have a new authentication token requested every 10 minutes, and I'm not sure if the browser will do the right thing and immediately request a new token if it wakes up after a long time.

Clarifications: I don't wan't to use cookies - I'm trying to build a web service here; and yes, the server will reject old and invalid tokens.

Javascript Solutions


Solution 1 - Javascript

As far as I've tested, it just stops and resumes after the computer wakes up. When the computer awakes the setInterval/setTimeout is unaware that any time passed.

I don't think you should rely on the accuracy of setTimeout/Interval for time critical stuff. For google chrome I discovered recently that any timeout/interval (that is shorter than 1s) will be slowed down to once a second if the tab where it's activated looses focus.

Apart from that the accuracy of timeouts/intervals is dependent on other functions running etc. In short: it's not very accurate.

So using interval and timeouts, checking the time against a starttime within the function started by it would give you better accuracy. Now if you start at 12:00, the computer goes to sleep and wakes up at 16:13 or so, checking 16:13 against 12:00 you are certain you have to renew the token. An example of using time comparison can be found here

Solution 2 - Javascript

Compare current datetime against datetime when the page was loaded, like so:

//Force refresh after x minutes.
var initialTime = new Date();
var checkSessionTimeout = function () {
    var minutes = Math.abs((initialTime - new Date()) / 1000 / 60);
    if (minutes > 20) {
	    setInterval(function () { location.href = 'Audit.aspx' }, 5000)
    } 
};
setInterval(checkSessionTimeout, 1000);

Solution 3 - Javascript

Here is my code :

<!doctype html>
<html>

<body>
<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 120000)"/>

</body>
<script>


</script>
</html>

I have taken three scenarios that might answer the question.

Scenario 1: At 00 Seconds click on 'Start Timer' button . At 25 seconds computer falls asleep. At 1min 40 seconds wake up computer. At 2mins Alert is displayed.

Scenario 2 : At 00 Seconds click on 'Start Timer' button . At 26 seconds computer falls asleep. At 3 mins, I wakeup the computer. The Alert is displayed.

Scenario 3 : This one is truly astounding.

<input type="button" name="clickMe" id="colourButton" value="Start Timer" onclick="setTimeout('alert(\'Surprise!\')', 600000)"/>

At 00 Seconds I click on 'Start Timer' button. At around 1min 30 seconds the computer is on hibernate mode (my pc takes a minute to initiate hibernate)

At 8 mins I turn the laptop on. At 10 mins exactly, the alert pops up.

PS: This is my first ever comment on Stack Exchange. I prefer to execute code and view results rather than infer from theory.

Solution 4 - Javascript

The behavior is based on both the browser and the operating system. The OS handle sleep and individual apps often don't account for it.

What will most likely happen is that the OS will come back up with the same time remaining on the timer as when it was shut down. The other possibility is that it won't fire at all.

If it is really a concern, you will probably want to be better safe than sorry and store a time stamp of when the token was initialized and use setInterval to check it periodically (say twice a minute).

However, security should not be just a client side thing. Make sure that your server throws an error if an old / invalid token is used and that the Ajax behaves appropriately in response.

[edit] I agree with the other post that it might fire immediately on the next tick. Resig's blog post is very good.

Solution 5 - Javascript

Based on Ben's answer, I created the following util. You can tweak the sampling duration, however I use it just like this for token refreshing:

const absoluteSetInterval = (handler, timeout) => {
  let baseTime = Date.now();
  const callHandler = () => {
    if (Date.now() - baseTime > timeout) {
      baseTime = Date.now();
      handler();
    }
  };
  return window.setInterval(callHandler, 1000);
};

const absoluteClearInterval = (handle) => window.clearInterval(handle);

Solution 6 - Javascript

Behaviour of JavaScript timers (setTimeout) in several scenarios.

  1. When the thread is free and the timeout fires: The timer is fired immediately after the timeout. It might have certain imprecision of about 0-5 ms (typical scenario).
  2. When the thread is super busy (huge loop) long enough to pass the timer timeout: The timer will be executed immediately after the thread is freed.
  3. When there is an alert: Same behaviour as 2.
  4. When the thread is paused because our laptop went to sleep: I have seen several things. But most common is total inaccuracy and ignore of the time spent during sleeping.

Since timers in JavaScript are based on CPU ticks, and the CPU is sleeping, then the timer is completely paused and resumed as 'since nothing would have happen'.

Solution 7 - Javascript

In John Resig's blog the timers are said to be using "wall clock". I believe that the events will fire immediately after the machine is resumed because setTimeout() doesn't guarantee an execution is a specific point in time but as soon as possible after the specified interval. However, I haven't checked it myself.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSudhir JonathanView Question on Stackoverflow
Solution 1 - JavascriptKooiIncView Answer on Stackoverflow
Solution 2 - JavascriptBenView Answer on Stackoverflow
Solution 3 - JavascriptDannyBoiView Answer on Stackoverflow
Solution 4 - JavascriptAndrew CuriosoView Answer on Stackoverflow
Solution 5 - JavascriptErez CohenView Answer on Stackoverflow
Solution 6 - JavascriptJosé CaboView Answer on Stackoverflow
Solution 7 - JavascriptEvgeny ShadchnevView Answer on Stackoverflow