Re: [ServiceWorker] Event queuing model for SW (#649)

There are two models that I can think of: (A) the discard-when-terminate model and (B) the external queue model.

(A) basically is this: https://github.com/slightlyoff/ServiceWorker/issues/649#issue-60629643. When terminate a worker is executed, it doesn't requeue the tasks. Those tasks are discarded as they are in dedicated workers / shared workers.

(B) needs task queue(s) associated with the registration. And the service worker's event loop should process the registration's task queue instead of its own task queue in a way. It'd be like:
A _service worker registration_ has an associated **task queue**.
A _service worker_'s _responsible event loop_ must process its _containing service worker registration_'s _task queue_ instead of its own _task queue_.
(I assumed the way it specifies makes sense. @annevk does it?)

(A) is simple. When terminate a worker is executed, the UAs can simply terminate those fetches and discard the tasks. Assuming the termination is an abnormal case (as we provide waitUntil, and all the operations are guided to be written async, etc), clients can easily recover by reload itself. Yeah, but the clients have to do that.

(B) The browsers (so and the clients) will not lose their events. But when the browser is closed and reopened, those unwanted events in the queue should be processed. (Maybe it can be an advantage to particular functional events like push?) Moreover, when the service worker's activation fails, a massive number of events may be piled up in the registration's task queue.

Thanks @jakearchibald for the use cases to think of. Here's my thought:
> The browser has 100 fetch events queued, but the user navigates or hits "stop". Firing those 100 events would be wasteful, ideally the browser should be able to take them out of the queue. The SW may not be able to terminate, as the navigated-to page may also need the SW.

(This issue seems orthogonal to both (A) and (B) I think.) Ideally yes. But I'm concerned that this requirement will add complexity like tasks having to maintain/access additional information about the request's client and the algorithm having to remove those corresponding tasks from random positions which may not be the top of the queue. Assuming all the queued tasks will do async jobs, I'm leaning to just let them be processed. The navigation or the user abort will terminate the ongoing fetches anyway.

> The browser has 100 fetch events queued, but the user closes the browser. Firing those 100 events is probably not possible, but they shouldn't be fired next time the browser opens - the reopening of the page will refire them.

Yes, this can be a disadvantage of (B). 

> The browser has fetches & push events queued while the activate event for the target ServiceWorker is underway. However the activation fails leaving the registration without an active worker. I guess the queue should remain at this point? Added this concern to #659 (comment) - worried about a large buildup of events here.

This is a disadvantage of (B). As @jakearchibald pointed, queuing (possibly) massive number of the functional events until the worker is successfully activated seems not plausible. (The current Handle Fetch (step 15.2) falls back to the network in this case.)

> The browser has 10 fetch events queued, 3 fired and awaiting response, and an additional push event with an unsettled waitUntil. The ServiceWorker crashes for reasons unknown. I think the three fetch events & push should be treated as if they were given a rejected promise. The SerivceWorker should restart and the queue should continue to process (the previously fired events are not rescheduled unless they typically do when their waitUntil/respondWith promise rejects, as is the case with one-off background sync).

(B) will do this. For (A), the clients should reload. (A push event should have been lost in this case.)

Thoughts?

---
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/649#issuecomment-90883403

Received on Wednesday, 8 April 2015 11:23:00 UTC