Skip to content
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

Request: high precise timer #34

Open
hanguokai opened this issue Jul 1, 2021 · 12 comments
Open

Request: high precise timer #34

hanguokai opened this issue Jul 1, 2021 · 12 comments
Assignees
Labels
enhancement Enhancement or change to an existing feature follow-up: chrome Needs a response from a Chrome representative neutral: firefox Not opposed or supportive from Firefox neutral: safari Not opposed or supportive from Safari opposed: chrome Opposed by Chrome

Comments

@hanguokai
Copy link
Member

alarms api only support "1-minute timer" and may delay some time(e.g. 30 seconds). So this is not a precise timer, it cannot be used to do clock-like functions.

I suggest in manifest.json add a new "highPreciseAlarm" permission, that supply precise timer function.

@dotproto
Copy link
Member

dotproto commented Jul 7, 2021

To my knowledge the Alarms API was added expressly to wake event pages so they could perform background work like fetching feeds for an RSS reader (source). The current 1-minute resolution seems to be an attempt to balance an extension's need to perform periodic work against the browser's desire to keep event pages from loading unnecessarily.

@hanguokai, can you share more information about your use case? Why does exposing a high precision timer in a background context make possible? How are alternatives insufficient?

@hanguokai
Copy link
Member Author

hanguokai commented Jul 7, 2021

I explained it at https://bugs.chromium.org/p/chromium/issues/detail?id=1159691

Example 1: Clock App

set badge text = "hh:mm", and update it every minute at zero second. e.g. update time at 12:20:00(zero second). But if use alarm api with 1-minute interval, it wake up at 12:20:35, 12:21:35, 12:22:35 ... random delay some seconds(< 60 seconds), it does not guarantee to wake up at seconds-level precise. Not only one user said my clock extension is not accurate, because it delay many seconds.

Not only update badge text for current time. My clock extension has a function that announce and/or notification the time at every hour(zero minute, zero second)/30min/20min/15min ... It needs to wake up at zero second.

Example 2: Custom Reminders

User set a reminder at "hh:mm". Usually, user expect the reminder happen at zero second, not delay too many seconds. For example, a teacher, student used it as clock for testing or alarm.

If alarm api can't supply precise alarm, the only way to workaround is that use a MV2 persistent background page with setTimout/setInterval .

@hanguokai
Copy link
Member Author

hanguokai commented Jul 7, 2021

There is a video talk about alarm api 8 years ago https://youtu.be/vdMBihN28NI?t=347

Alarm api may delay some time because they consider performance reason, e.g. there are many alarms created by one or multiple extensions. So they align all alarms that created by all extensions to at most 1 minute as minimum interval.

@Jack-Works
Copy link

If there is a at most 1 minute delay, you can set your alarm one minute before and check the current time.

@hanguokai
Copy link
Member Author

If there is a at most 1 minute delay, you can set your alarm one minute before and check the current time.

This is not a reliable workaround. For example, when the background/SW wake up, it’s 30 seconds early, no way to keep alive another 30 seconds reliably. It may terminate soon. Also, this method is not suitable for updating every minute.

@cuylerstuwe
Copy link

cuylerstuwe commented Aug 12, 2021

"can you share more information about your use case? Why does exposing a high precision timer in a background context make possible? How are alternatives insufficient?"

In a previous extension I worked on for a growing startup, a core business proposition of the platform revolved around accurately tracking time spent on tabs.

It was pretty important for this information to be as accurate as possible, as small differences could be actionable.

Out of the myriad approaches we tried, the notion of running timers per-tab (e.g., in content scripts) ended up being nonperformant (as well as insufficiently accurate) -- the lack of inherent sync meant that it was prone to over/undercounting, and/or it was an extremely convoluted process to try to meaningfully sync the results.

The most effective timing approach (for both accuracy and performance) involved setting up a centralized timer in background.js via setInterval. This ran approximately 1x/sec, identified the active window/tab, and requested the relevant information to associate with the tick.

They were a great team, and from time to time, I've regretted leaving. But now that MV3 doesn't seem to offer any clear way of enabling their software, I'm a little glad that I didn't stay.

@xeenon xeenon added the enhancement Enhancement or change to an existing feature label Sep 2, 2021
@Rob--W Rob--W added opposed: chrome Opposed by Chrome neutral: safari Not opposed or supportive from Safari neutral: firefox Not opposed or supportive from Firefox labels Mar 20, 2024
@oliverdunk
Copy link
Member

We discussed this at our in-person meeting in San Diego.

In general, alarms should be fairly accurate and fire with significantly less than 30 seconds of delay. In the cases where it doesn't - for example if the background context is running a blocking loop or showing an alert() - we would not be able to avoid it even with a new high precision permission.

The best approach in this case would be to have a regular alarm to make sure your background context is alive, and within the background context use a setInterval which can run with higher frequency.

Also, a tangential note - Chrome recently made a change to reduce the minimum frequency of alarms to 30 seconds: https://developer.chrome.com/docs/extensions/whats-new#chrome_120_minimum_alarm_granularity_reduced_to_30_seconds.

@oliverdunk oliverdunk closed this as not planned Won't fix, can't repro, duplicate, stale Mar 20, 2024
@xeenon
Copy link
Collaborator

xeenon commented Mar 21, 2024

WebKit is also changing to a 30 second minimum interval. WebKit/WebKit#26259

@hanguokai
Copy link
Member Author

hanguokai commented Apr 12, 2024

for example if the background context is running a blocking loop or showing an alert() - we would not be able to avoid it even with a new high precision permission.

This is not a case for this issue.

In general, alarms should be fairly accurate and fire with significantly less than 30 seconds of delay.

This is not true. You're a nice guy, but technically you don't really understand this issue.

Let me illustrate this issue with code.

function getTime(number) {
  return new Date(number).toLocaleTimeString();
}

chrome.alarms.onAlarm.addListener(alarm => {
  let now = Date.now();
  let diff = now - alarm.scheduledTime;
  console.log(`${alarm.name} delay: ${diff}ms, expect: ${getTime(alarm.scheduledTime)}, now: ${getTime(now)}`);
});

async function test() {
  await chrome.alarms.clearAll();
  let now = Date.now();
  console.log(`Start Time: ${getTime(now)}`);

  // alarm A
  let expectTime = [];
  for (let i = 1; i < 6; i++) {
    expectTime.push(getTime(now + 30000*i));
  }
  console.log(`Alarm-A expect: ${expectTime.join(', ')}`);
  chrome.alarms.create("alarm-A", {
    periodInMinutes: 0.5
  });

  // delay 15s for alarm B
  expectTime = [];
  for (let i = 1; i < 6; i++) {
    expectTime.push(getTime(now + 15000 + 30000*i));
  }
  console.log(`Alarm-B expect: ${expectTime.join(', ')}`);
  setTimeout(() => {
    chrome.alarms.create("alarm-B", {
      periodInMinutes: 0.5
    });
  }, 15000);
}

// start test
test();

You may see this output:

Start Time: 2:42:32 PM
Alarm-A expect: 2:43:02 PM, 2:43:32 PM, 2:44:02 PM, 2:44:32 PM, 2:45:02 PM
Alarm-B expect: 2:43:17 PM, 2:43:47 PM, 2:44:17 PM, 2:44:47 PM, 2:45:17 PM
alarm-A delay: 627.281982421875ms, expect: 2:43:02 PM, now: 2:43:03 PM
alarm-B delay: 15627.6689453125ms, expect: 2:43:17 PM, now: 2:43:33 PM
alarm-A delay: 629.281982421875ms, expect: 2:43:32 PM, now: 2:43:33 PM
alarm-B delay: 15629.6689453125ms, expect: 2:43:47 PM, now: 2:44:03 PM
alarm-A delay: 632.281982421875ms, expect: 2:44:02 PM, now: 2:44:03 PM
alarm-B delay: 15630.6689453125ms, expect: 2:44:17 PM, now: 2:44:33 PM
alarm-A delay: 633.281982421875ms, expect: 2:44:32 PM, now: 2:44:33 PM
alarm-B delay: 15632.6689453125ms, expect: 2:44:47 PM, now: 2:45:03 PM
alarm-A delay: 635.281982421875ms, expect: 2:45:02 PM, now: 2:45:03 PM

Note that in the output above, alarm-B is always 15 seconds behind schedule. This is a reproducible result. If you run test() multiple times, the delay may be different compared with previous run, but the delay is stable in a test.

Note that you must run test in a packed extension (.crx file) or run code in an extension installed from Chrome Web Store, because there is no alarm restriction in an unpacked extension (dev mode). You can pack an extension with extension-update-testing-tool, and drag and drop the .crx file to a Chromium (Chrome doesn't allow to use an unknow .crx file now).

Note that you can create two extensions to reproduce this issue. For example, in extension-A create alarm-A, then delay 15s in extension-B create alarm-B. Alarms in different extensions can cause this problem too, they influence each other.

This issue has existed since the beginning of the alarm API, as it was designed in this way. To further explain, the current minimum time schedule (30 seconds or 60 seconds in the past) is to manage all the alarms of all extensions together. So there will be this problem.

The goal of #34 is to support alarms that get rid of this limitation. For example:

chrome.alarms.create("alarm-name", {
    periodInMinutes: 0.5,
    highPrecise: true
});

@Rob--W
Copy link
Member

Rob--W commented Apr 25, 2024

@oliverdunk Adding follow-up: chrome Needs a response from a Chrome representative here - during the meeting it sounded like Chrome was willing to consider higher resolution timers. Does that change the opposed: chrome Opposed by Chrome label here?

@oliverdunk
Copy link
Member

@oliverdunk Adding follow-up: chrome Needs a response from a Chrome representative here - during the meeting it sounded like Chrome was willing to consider higher resolution timers. Does that change the opposed: chrome Opposed by Chrome label here?

I'm slightly reluctant to change the label given the current state of this issue. We're open to considering reducing the granularity with which we check alarms and the minimum interval a developer can specify. We don't plan to add any new properties like highPrecise to the API though and would be unlikely to reach true high precision (anything under a second).

I think leaving the opposed label, and additionally follow-up for the Chromium change makes sense? If we wanted to clarify the ask in the issue I'd be comfortable changing the label then, but I'm not sure that's worth the effort. Open to thoughts though.

@oliverdunk oliverdunk self-assigned this Apr 26, 2024
@hanguokai
Copy link
Member Author

As mentioned in the meeting, if the minimum interval is reduced to 1 second, then this problem is solved without requiring any API changes (such as a new permission or parameter). But if Chrome don't want to reduce the interval to 1 second, then we need to a proposal to support high-precision (delay of less than a few seconds) alarms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement or change to an existing feature follow-up: chrome Needs a response from a Chrome representative neutral: firefox Not opposed or supportive from Firefox neutral: safari Not opposed or supportive from Safari opposed: chrome Opposed by Chrome
Projects
None yet
Development

No branches or pull requests

7 participants