Extension API can extend service worker lifetime!

494 views
Skip to first unread message

Jackie Han

unread,
Mar 10, 2023, 9:34:33 AM3/10/23
to Chromium Extensions
Given the changes in https://developer.chrome.com/blog/longer-esw-lifetimes/, I think frequently requesting the system state and updating the icon may actually be enough activity to keep your service worker alive. 
 
You're right that setInterval doesn't extend the lifetime, but calls to chrome extension APIs can.
 
I want us to look at improving the documentation around this because I think the blog post is accurate, but a little vague on exactly how we define certain behaviour 

I just upgraded my "System Monitor" extension (persistent background page in MV2) to MV3. Beyond my imagination, it works!

I made a simplified version of the extension to illustrate this.

// in service worker
let count = 0;
setInterval(function() {
  count = (count + 1) % 1000;
  chrome.action.setBadgeText({text: count.toString()});
}, 5000);


The above code is very simple. It updates the badge text every 5 seconds, going on forever.
The result is that SW will stay alive forever.

But if you remove the extension api call (`setBadgeText`), SW will be terminated after 30s.

let count = 0;
setInterval(function() {
  count = (count + 1) % 1000;
  // chrome.action.setBadgeText({text: count.toString()});
}, 5000);


I read this article https://developer.chrome.com/blog/longer-esw-lifetimes/ . What I understand is that new extension events can extend SW lifetime, but didn't expect that general extension API calls can also extend its lifetime.

So, this behavior is from Chrome 110? Will it remain this behavior in the future?

Thanks
Jackie Han

Oliver Dunk

unread,
Mar 10, 2023, 10:23:40 AM3/10/23
to Jackie Han, Chromium Extensions
Hi Jackie,

Glad to hear that you managed to get your extension working! The main thing I wanted to get a feel for was if our current lifetime behaviour was sufficient for your use case. It sounds like (assuming the behaviour in Chrome today is what we plan to keep) it is :)

On extension API calls extending service worker lifetimes - since you've asked, I just want to double check one more time and confirm with the engineering team that we intend to keep this behaviour before I say anything for definite. I'm sorry for mentioning it before being able to say for sure. I'm pretty sure this is working as intended, but you're right that we didn't mention this in our blog post, and I definitely don't want you to rely on something that we have plans to change.

I'll try to reply soon, but it might not be until Monday because I think some of the engineering team are OOO today.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/CAAgdh1KWnXAdyQhN6ERw7yQJyp25ncg0YLzkHt-Akq%3DZZBFjDA%40mail.gmail.com.

wOxxOm

unread,
Mar 10, 2023, 5:28:34 PM3/10/23
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Jackie Han
This behavior is definitely a bug, there's no absolutely no doubt about that.

wOxxOm

unread,
Mar 10, 2023, 5:45:06 PM3/10/23
to Chromium Extensions, wOxxOm, Oliver Dunk, Chromium Extensions, Jackie Han
To elaborate, the rule itself is simple: any self-prolongation is a bug. It means only events initiated by an external entity are allowed to prolong the lifetime of the service worker. On the other hand this rule doesn't make much sense for extensions as they can easily circumvent it by sending a message from a content script that runs in a web page in any tab. This is yet another evidence that choosing service worker technology was a mistake.

wOxxOm

unread,
Mar 11, 2023, 9:47:38 AM3/11/23
to Chromium Extensions, wOxxOm, Oliver Dunk, Chromium Extensions, Jackie Han
Correction: "events initiated or confirmed by an external entity are allowed to prolong the lifetime" e.g. in case the SW opened a port connection to a tab.

Oliver Dunk

unread,
Mar 13, 2023, 11:44:31 PM3/13/23
to Jackie Han, Chromium Extensions
Hi Jackie,

I confirmed with the team today and I'm happy to say that this is the intended behaviour and not a bug. The change was made as part of the work we were discussing in that blog post so I believe it would have also shipped in Chrome 110.

We don't have any immediate plans to make changes here, but I do want to call out that our goal is to avoid terminating extensions which are actively performing work, and not to support service workers running indefinitely. As we said towards the end of the post, we may tweak things over time, in response to trends or in particular if we see the behaviour being abused. Building a robust extension which can be terminated at any point, especially when inactive, remains important.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

wOxxOm

unread,
Mar 14, 2023, 12:58:50 AM3/14/23
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Jackie Han
> I confirmed with the team today and I'm happy to say that this is the intended behaviour and not a bug

Looks like they didn't understand the issue.

> our goal is to avoid terminating extensions which are actively performing work

Extensions are still terminated when doing any work except calling a `chrome` API. If such weird ad hoc and non sequitur change of specification and historical behavior in MV2 event pages is indeed intended, self-prolongation via repeated calls to a chrome API should be documented explicitly. Until then it's just a bug and we can't rely on it.

Jackie Han

unread,
Mar 14, 2023, 3:45:15 AM3/14/23
to wOxxOm, Chromium Extensions, Oliver Dunk
Extension service workers usually do more heavy tasks than standard Web service workers. I think an event-based plus relatively loose and longer life cycle is conducive to the implementation and stability of extension background scripts. So I'm in favor of behavior change in this direction.

Ideally, background scripts should not be stopped until they have completed their tasks. The life cycle can be extended, whether from external or internal needs.

But there are indeed some places that are confusing developers at the moment. For example, which ones can extend lifetime and which ones can not; What counts as a long task and what doesn't; What counts as fair use and what counts as abuse. These places are vague.

At present, it is a bit confusing that only extension api calls can prolong life. On the other hand, the extension api call does indicate that it is doing extension's work. At an organizational (non-technical) level, large projects like Chromium are made up of many different teams. The extension team has the power to decide the behavior of the extension API, but not much power over other parts. So, I can imagine why extension API can extend extension service worker's life cycle.

wOxxOm

unread,
Mar 14, 2023, 11:57:21 AM3/14/23
to Chromium Extensions, Jackie Han, Chromium Extensions, Oliver Dunk, wOxxOm
I have been always advocating for loosening the restriction but it should be done properly, we shouldn't justify a blatant mistake/misunderstanding by imagining non-existent reasons behind it, at least not until this is explicitly confirmed in the documentation.

> What counts as a long task and what doesn't; 

It lacks practical examples (code) though.

> What counts as fair use and what counts as abuse. These places are vague.

+1

> The extension team has the power to decide the behavior of the extension API, but not much power over other parts. So, I can imagine why extension API can extend extension service worker's life cycle.

No, there's no such division, the extension team can make independent decisions over extension SW lifetime as long as those are reasonable, of course. Behavior of code should be consistent and logical i.e. all kinds of work should prolong the lifetime, so such a weird non-logical exception must be explicitly stated in a commit in the source code (or a comment in the review of this commit) that explicitly states the intent to keep the SW alive for just `chrome` calls.

Quoting Oliver Dunk:

> The change was made as part of the work we were discussing in that blog post

No, it wasn't. While it's indeed introduced by https://crrev.com/c/4022172 in Chrome 110, but if you look at the code + description + comments you'll see the intention was to account properly for externally initiated requests e.g. triggering a chrome API event listener, definitely not for internally initiated calls to chrome API methods, so there is no doubt that the new behavior was not intended, in other words it's an accidental bug. If you want to retroactively overwrite the objectively existing history you'll need to do it explicitly both in the documentation and in the source code.

Chrys Garnant

unread,
Mar 14, 2023, 2:06:22 PM3/14/23
to Chromium Extensions, wOxxOm, Jackie Han, Oliver Dunk
re:  "Extension service workers usually do more heavy tasks than standard Web service workers..."

Indeed they do.

Somehow there seems to be a perception that stateless behavior environment is the only thing that extensions  (or background pages) do or can live within.As many comments, questions and oh-my-gosh-wtf-do-I-do-now conversations here should have alluded to by now, this is far from the case. Something should seem wrong with the abstract model if there are a lot of round pegs not fitting into square holes. 

Stateless service workers are not the Unified Field Theory / Theory of Everything.  Be that as may ---

There seems to be a discussion about potential 'abuse' of stateful behavior . The use of the word 'abuse' is qualitative and incredibly subject to opinion and religiousity. (sorry, Bill Maher), and as legal minds would say 'potential' assumes facts not in evidence [unless we are inside a Minority Report].

So let's focus on the fact that there are both stateful and stateless extensions and that they are both valid - neither one is ''abusive'. As many discussions have tried so hard to illuminate, stateful behaviors are used to SAVE resources (cpu time, memory, and perceived responsiveness) in addition to functionality.  I ask is that not the point of this whole exercise??? [Just wondering.]

re: "background scripts should not be stopped until they have complete their tasks"

How can anyone pre-suppose what 'completing their tasks' means? Simply because an execution thread is 'idle' does not mean that it has 'completed its task'. ***

It could be waiting for user interaction with various foreground parts of the extension to then communicate with a tabs content scripts or vice versa.  There are no time-limits on human interaction nor on the tab's behavior that would then trigger such a communication - that then depends upon a stateful environment to serve the needs of the user. Why? because if the stateful condition disappears we have only frustrated the user in one way or another - [not just caused a complete redesign and re-coding of the extension, [sarc-on] but then we know we all have limitless resources to do this [sarc-off]  This is either because it is just plain impossible to recover state and connections implying that state OR recovering browser execution context AND application state consumes so many resources in the first place (so much more than just maintaining stateful-ness).

Why is it so unacceptable to be stateful when it truly addresses the needs of the 'application' and of the consumer?

Is there not some other way of dealing with this instead of creating a convoluted 'pretzel' to shoe-horn something in a model-of-everything that does not fit the model-of-everything?

If there is still the perception of stateful 'abuse', then, at the very least, allow any extension to be granted stateful permission if nothing else can be imagined!

Thanks, respectfully, 
Chrys


*** If for some reason the reader does not perceive this as a problem,  imagine how, not-in-an-extension-environment, bloody frustrating it is to have been working on a web-based application only to be called into an extended zoom meeting - then coming back and finding, upon swtiching back to that TAB, that the application's TAB state has been wiped and the url is reloaded being from square 0 . [This is ACTUAL behavior :: bug in v109 trying to make tab behavior be like a service worker.]  Would you not be screaming?  [Analogy] - Now imagine if that little girl were ... [from Matthew M's (Jake Brigance's) summation to the jury in A Time to Kill.]

2B | !(2B) E ? }-> : 0
[It is getting to  tiring dealing with the 'slings arrows of outrageous fortune'....]

Simeon Vincent

unread,
Mar 14, 2023, 4:27:55 PM3/14/23
to Chrys Garnant, Chromium Extensions, wOxxOm, Jackie Han, Oliver Dunk
I'm a little biased here, but IMO one of the challenges here is that the extension platform doesn't provide extension developers with a good way to tell the browser how long a given task takes to perform.

Normal service worker events give developers a way to signal that event processing has finished via the ExtendableEvent interface's `waitUntil()` method. When called with a promise, this method allows the developer to signal that the event handler is performing work as long as the promise is unresolved. This mechanism is directly used by the "install" and "activate" events and indirectly by the "fetch" event's `respondWith()` method. Extensions can't directly inherit this interface because the extension event model has a major divergence from the web platform event model; unlike web events, extension events do not pass the event handler a single event object that could expose these task tracking methods.

I see a couple of ways that the platform could evolve to address this:

1. Add another argument to the signature for event handler callbacks to expose a property bag. This could be used to expose `waitUntil()` and possibly other properties in the future as needed. 
2. Introduce a separate task tracking mechanism that behaves similarly to `waitUntil()`. For example, `runtime.createTask(Promise)`. 
3. Introduce an alternate event registration interface that makes extension events behave more like web platform events, including implementing the Event and ExtendableEvent interfaces as appropriate.

IMO none of these are perfect solutions and some of them may not even be viable.


I confirmed with the team today and I'm happy to say that this is the intended behaviour and not a bug

I'm honestly a bit surprised by this. As I've been thinking about extension service worker lifetimes, event processing has been central to my mental model. Extensions receive events and perform actions in response to them. In the case of periodic or batch work, alarms (and their events) could be used to perform those operations on a regular schedule. Allowing extension platform method calls to extend the lifetime strikes me as odd because I think it makes reasoning about the context's lifetime much more difficult.

 
If such weird ad hoc and non sequitur change of specification and historical behavior in MV2 event pages is indeed intended, self-prolongation via repeated calls to a chrome API should be documented explicitly.

I'm compelled to stress again that there is no specification or formal standard for the Manifest V2 extension platform. Chromium's implementation is something of a de facto standard, but there is no specification that describes the lifecycle or lifetime handling of event pages. That said, I agree that we would all benefit from having this defined and documented, and I'm very keen on drafting such a specification in the WebExtensions Community Group.


Simeon - @dotproto

Chrys Garnant

unread,
Mar 14, 2023, 4:56:52 PM3/14/23
to Simeon Vincent, Chromium Extensions, wOxxOm, Jackie Han, Oliver Dunk
re: " Allowing extension platform method calls to extend the lifetime strikes me as odd because I think it makes reasoning about the context's lifetime much more difficult..."

Again, the problem is with THAT exact model - believing that anyone should even be thinking about a context's lifetime at all.  All the rest - inventing this hoop, this hurdle, this steeplechase of this event, that event, this method, this other method ad nauseum, as work-arounds that address the symptom and not the disease simply belies the fact that the model is in error - both practically and architecturally  The models, not the workarounds, are what need to be addressed. [I know, beating the dead horse, but, if there is to be a solution, work-arounds are not long term solutions.  If mv2 lasted as long as it has, think about the dead inertia that will become with mv3! 

So it's time to think clearer and at a more global architectural level.  I sincerely hope that we can.

Chrys


2B | !(2B) E ? }-> : 0

Oliver Dunk

unread,
Mar 14, 2023, 11:27:54 PM3/14/23
to Chrys Garnant, Simeon Vincent, Chromium Extensions, wOxxOm, Jackie Han
Just catching up on this thread - there's been a lot of great discussion so thank you to everyone who has contributed.

To reiterate, we're very well aware of the implications of this change and it was made intentionally. I completely agree that there is a lot of importance in documenting changes like this, especially before it feels safe to rely on them. As I mentioned in my first post, that's something we're discussing internally and I hope we can do sooner rather than later.

I definitely agree with the sentiment that there are currently gaps in what is considered work. The change we're discussing here is one example of something we're doing to try and help with that, but there's definitely still more to do. I think the types of mechanisms Simeon mentioned are ones that are examples of what may make sense, but that definitely needs more thought.

I also just wanted to speak to the concern that we may later use abusive behaviour as a way to justify removing affordances like this. While it's hard to say exactly what will and won't happen in the future, our goal with any changes there would be to prevent very clear cases where a developer is keeping a service worker alive that could otherwise be safely shut down.

Please keep the feedback coming. In particular, I'm interested to hear if there are examples of work that should extend the service worker lifetime but doesn't today.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

wOxxOm

unread,
Mar 15, 2023, 12:00:39 AM3/15/23
to Chromium Extensions, Oliver Dunk, Simeon Vincent, Chromium Extensions, wOxxOm, Jackie Han, Chrys Garnant
>  To reiterate, we're very well aware of the implications of this change and it was made intentionally. 

There's no such indication neither in the source code nor in comments for https://crrev.com/c/4022172. All the facts say it's an accidental bug. You seem to confuse chrome events with chrome methods.

> The change we're discussing here is one example of something we're doing to try and help with that

No, we're discussing an unforeseen bug made while making the intended change in behavior of SW lifetime for chrome events.

> if there are examples of work that should extend the service worker lifetime but doesn't today.

Literally anything except calling a chrome API doesn't extend the lifetime of SW i.e. any code will be terminated at the 30 second mark of the idle timeout. That's because this is the correct behavior per SW specification.

wOxxOm

unread,
Mar 15, 2023, 12:12:56 AM3/15/23
to Chromium Extensions, wOxxOm, Oliver Dunk, Simeon Vincent, Chromium Extensions, Jackie Han, Chrys Garnant
One popular painful example of something that should prolong the SW lifetime but currently doesn't would be a long running fetch(). It's not that unusual for fetch() to take more than 30 seconds when the internet connection is spotty or the network is overloaded or the server is slow.

Another popular example is setInterval/setTimeout. The only way to make it work past the idle timeout is to artificially prolong the lifetime of the SW. It's not a good programming pattern because everyone will just always prolong the lifetime via the chrome call bug in order to avoid the inherent deficiency in ManifestV3 design that pretends there's no need for persistent background scripts.

wOxxOm

unread,
Mar 15, 2023, 12:35:37 AM3/15/23
to Chromium Extensions, wOxxOm, Oliver Dunk, Simeon Vincent, Chromium Extensions, Jackie Han, Chrys Garnant
  • WebSocket connections
  • ongoing IndexedDB requests
  • an open MessageChannel, BroadcastChannel
  • any asynchronous code awaiting a non-chrome Promise

Anthony Lucas

unread,
Mar 15, 2023, 2:59:12 PM3/15/23
to Chromium Extensions, wOxxOm, Oliver Dunk, Simeon Vincent, Chromium Extensions, Jackie Han, Chrys Garnant
I have to agree here.

It is impossible for Chromium to know if there is active work to do without creating an explicit application life-cycle interface (something like activities).
All of this shoe-horning and guessing is destroying the extensions platform.


Three things make this an impossible design to balance:

1) Lack of real control over the base technology - service workers (The fact that you can make changes is lip-service because it will always be very hard to justify the cost of duplicating work. Every time a best choice vs compromise decision comes up, it will be the compromise, always)
2) Trying to do everything automagically without creating a real structure for extension code where you can actually understand what they are doing.
3) Taking an adversarial stance instead of a supporting stance in trying to bring conformance to an existing eco-system.


Basing everything on service workers is an unfortunate choice in my opinion. It will be very hard to balance project decisions that need to be made in a way that can be truly beneficial, because the large amount of code inherited is in fact poison to the natural architectural decisions that should have had a chance to be made for the extensions platform.

As a software architect, it can be very important to recognise when decisions cannot be fixed through casual development in a way that would eventually lead to the best possible solution.

These bugs are not bugs, but instead side effects of something not being addressed. Addressing the issue does not mean turning around. It simply means taking a step back and giving yourself a chance to create a future that is in alignment with your intended goals.

There is an entire code architecture totally missing in order to achieve the level of involvement in application state that MV3 is attempting.  

The browser will need a way to be able to stop and start extension tasks, and unload memory at-will, without losing state. Anything less is just a sidetrack.

Simeon Vincent

unread,
Mar 15, 2023, 5:43:34 PM3/15/23
to Anthony Lucas, Chromium Extensions, wOxxOm, Oliver Dunk, Jackie Han, Chrys Garnant
>  To reiterate, we're very well aware of the implications of this change and it was made intentionally.

There's no such indication neither in the source code nor in comments for https://crrev.com/c/4022172. All the facts say it's an accidental bug. You seem to confuse chrome events with chrome methods.

There's a fact that you're ignoring: Oliver is speaking on behalf of the Chrome extensions team and has explicitly said that this change is intentional. I'm no longer with Google; Oliver is now the extension's community's primary contact point with the Chrome team.

Simeon - @dotproto

wOxxOm

unread,
Mar 15, 2023, 7:21:16 PM3/15/23
to Chromium Extensions, Simeon Vincent, Chromium Extensions, wOxxOm, Oliver Dunk, Jackie Han, Chrys Garnant, Anthony Lucas
> There's a fact that you're ignoring: Oliver is speaking on behalf of the Chrome extensions team and has explicitly said that this change is intentional. I'm no longer with Google; Oliver is now the extension's community's primary contact point with the Chrome team.

I'm not ignoring facts, I'm only ignoring claims not based on facts. It doesn't matter how many Chrome team developers make such a claim if it's not based on observable facts because they could simply misinterpreted the issue, same as Oliver Dunk did, who already misinterpreted several other issues in this group. The blob article was about a specific fix for a specific bug (chrome events didn't restart the idle timer), there isn't a single indication anywhere that treating chrome methods as events was intentional. The observable facts say it's a bug and definitely not intentional change. Until a new observable fact such as an explicit confirmation in the documentation appears it will remain a bug.
Reply all
Reply to author
Forward
0 new messages