-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How should timers account for system sleep/suspend? #6759
Comments
@smaug---- @rniwa care to provide context on Gecko and WebKit? Pausing seems very much preferable to me and I don't think you cannot really rely on these being accurate anyway with background tab throttling, other tasks that might run long, etc. |
@shaseley do you happen to have some simple test case for this? |
I cobbled one together here, but unfortunately don't have anything that automates putting the computer to sleep/waking it back up. That page just lets you set a timer for some number of minutes and computes how long it took. But it was helpful for testing this locally. My testing methodology was to:
Those steps can probably be compressed, but I wanted to make sure the result was obvious. On my macbook (Big Sur), the timer expired after ~7.5-8 min of wall time on Chrome, FF, and Safari, so it was clear that timers were paused during sleep. I can test Android and probably Linux, but I'll need to work on getting more devices or crowdsourcing to test other platforms. |
Let's start a table:
|
Some more results, using the same methodology: start a timer for 5 min, sleep for 3 minutes soon after, observe the time. In cases were we say timers paused during sleep, the Thanks to @kjd564 for testing iOS and Windows! AndroidTesting was done on a Pixel 3a/Android 11.
iOSTesting was done on an iPhone 11 running iOS 14.6.
WindowsTesting was done on a Windows 10 laptop, running a recent version (10942.1083).
Note: On Windows, the timers went off at almost exactly 5 minutes. To verify that the device did in fact sleep, we looked at the event viewer and found sleep/wake logs during the time period that the device was put to sleep, which gives us additional confidence in the result. Note that these results are also in line with the behavior of |
The table is missing linux ;) |
LinuxRan the same test on a machine I had at home running Ubuntu 16.04.7 (Xenial):
Any other browser/OS combinations we want to try? |
Does it matter on Windows if the system is using good old 'S3' or the newer "modern standby" 'S0 Low Power Idle'? (Modern standby is even buggier on Linux than it is on Windows, but perhaps one has a machine where it works well enough for testing on linux too) |
Removing the |
We've been discussing a similar issue with the Alarms API in the WebExtensions Community Group. Chrome originally introduced the Alarms API as a way to perform As we discuss inconsistent behavior across browsers, bugs in existing implementations, and developer expectations, we are reconsidering how alarms should behave across sleep/suspend boundaries. The current consensus opinion is that time should continue to tick for alarms while a device is suspend. We commonly refer to this as using wall-clock time. For example, say it is currently 9:00 AM and an extension schedules an alarm for 9:10 AM. At 9:05 the user suspends the device and unsuspends it at 9:15. When the device wakes, the browser should dispatch events for alarms that were scheduled when the device was asleep. This means the 9:10 alarm will fire at 9:15. (If time did not dick while the device was alseep, the alarm event would not be dispatched until 9:20.) One of the considerations that lead us in this direction is that the Alarms API has more metadata about the scheduled operation than the web platform APIs. We can see this in the
Browser representatives participating in the WECG felt that this provides the extension developer with enough information to distinguish between alarm events if multiple fire when a device resumes from sleep/suspend. |
I'm wondering how system sleep/suspend should affect
setTimeout()
's waiting steps: should time pause during sleep, or should time continue to tick? Step 15 of the timer initialization steps says time should only tick for fully active documents and non-suspended workers. IIUC the former applies to BFCache, but I'm not sure if either are meant to take into account system sleep/suspend.As far as use cases and developer expectations go, I think there are some use cases where pausing time during sleep is fine and some where it isn't. Things like calendar notifications are an obvious use case where you'd want time to continue to tick during sleep, so the notification can be shown immediately upon resume if the timer expired while suspended (although maybe something like Notification Triggers is the solution here?). But there are also use cases where pausing time would be fine, e.g. deferring low priority work during loading.
In Chromium's implementation, the behavior unfortunately varies depending on the platform, which is something we want to fix. I'm not sure what other browsers are doing here. From an implementation standpoint, there can be a flood of work including expired timers that happens during resume (thundering herd problem), so having time pause during sleep can be helpful to mitigate this to some degree. But then developers would need workarounds to get realtime behavior [1].
While I do think aligning on a reasonable default here is the right first step, it might be beneficial to consider adding an option for developers to specify this behavior. There is precedent in other systems, e.g. POSIX timers.
For additional context, this came up recently in a couple places:
Writing the spec for the new
scheduler.postTask()
API. This provides another way to post delayed tasks, and we want to align withsetTimeout()
behavior.The behavior of clocks ticking during sleep came up in the context of
performance.now()
as there is some inconsistency on some platforms/browsers.Do folks have opinions on what this behavior should be?
[1] We've seen workarounds for this in already in JavaScript code, e.g. implementing "realtime timers" by periodically checking how much time has elapsed. This seems unfortunate for a few reasons, including from an energy perspective (more wake-ups in the background).
The text was updated successfully, but these errors were encountered: