-
Notifications
You must be signed in to change notification settings - Fork 312
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
Allow the addRoutes() to be called during installing #1744
Conversation
@domenic @sisidovski Will you review this? Note that Chromium code has not followed the change yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some questions:
- Should addRoutes be callable only synchronously within the event handler or while the event is active (aka while the service worker is installing)?
- Should addRoute execution delay installation of the service worker?
- Should addRoutes promise rejection trigger automatic failure of the service worker or should it be let to the website?
My preference so far:
- Allow calling addRoutes while the event is active.
- Have addRoute execution delay installation of the service worker.
- Leave failure of the installation up to the website.
Based on this, I would tend to keep the current API signature as is, addRoutes(RouterRule or sequence)
.
Do you mean that the while the service worker is installing is that the state is "installing"? Will you help me to understand corner cases that bring difference between two?
It should be. Or, there might be ambiguity on how the subsequent navigation will be handled.
Current Chromium implementation allows The thought behinds are:
As written above, let me ask details.
I think we agree on both 2. and 3.
Sure. I will work on that tomorrow. |
In general, I think we want to allow adding routes before the service worker information is stored persistently. I also think this might be handy for web developers.
Also, |
Thanks for the comment. I tried to make the returning promise lives with the event, I hope that is what you meant. |
Changes look good.
|
docs/index.bs
Outdated
|
||
Note: {{InstallEvent/addRoutes(rules)|event.addRoutes(rules)}} extends the lifetime of the event by default as if {{ExtendableEvent/waitUntil()|event.waitUntil(promise)}} is called. | ||
|
||
1. Run the following substeps [=in parallel=]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like it might be a little racy. Perhaps you should use the parallel queue infrastructure whenever you modify the list of router rules? Or maybe even when you access it as well?
I am curious how this maps to the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
I tried to fix that by using ServiceWorkerEventLoop.
In Chromium, mojo should be handled sequentially and it actually executed one by one as far as I understand.
- remvoed unnecessary type check. I added that for allowing the argument to be Promsie, which I reverted. - move fetch-event check inside the loop to make the code a bit simpler.
docs/index.bs
Outdated
Note: this step is for making |lifetimePromise| always fullfilled to avoid the install event failure. | ||
|
||
1. Let |serviceWorkerEventLoop| be the [=current global object=]'s [=event loop=]. | ||
1. [=Queue a task=] to run the following steps on |serviceWorkerEventLoop| using the [=DOM manipulation task source=]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not exactly what we want here.
|serviceWorker|'s list of router rules are used when matching a fetch, which happens out of process.
The usual way of handling this is to use [=in parallel=] to do manipulation out of process.
And we queue a task to actually go back to the service worker execution context.
This step could be replaced with something like:
1. [=In parallel], run the following substeps:
And then, at the end of these substeps:
1. [=Queue a task=] to run the following steps on |serviceWorkerEventLoop| using the [=DOM manipulation task source=]
1. Resolve |promise| with undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me ask on this more. I got confused for this.
To allow third-party libraries to set routes, addRoutes()
can be called multiple times. Also, to avoid ambiguity on the evaluation order, we want to force the rules to be evaluated in the added order.
Then, what happens if addRoutes()
is called multiple times with the suggested process? I am afraid its execution order is not guaranteed.
Since it says [=in parallel=], I suppose one procedure can be executed while the other is executed. If multiple addRoutes()
are called at once, there can be race condition and rules added at the same time may not be lost? That is my intention to make a task to do followings:
- get the existing rule.
- add the new rules.
- write back to |serviceWorker| [=list of router rules=]
Or, can we expect the deterministic execution order for [=in parallel=]?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, we definitely want to preserve determinism.
The solution is probably to use a parallel queue, like https://w3c.github.io/webcodecs/#codec-work-queue, and use it.
That said, this is an existing issue in the service worker spec, see cache algorithms for instance.
I would go with a comment stating that it is expected that the order of the rules is preserved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I tried to revised it to use the parallel queue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If using the parallel queue, you need to queue a task on the service worker event loop to resolve the promise. We are not expected to resolve promises from a parallel queue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure.
I guess I got the same comment from @domenic and I hope the recent one resolves this.
Thanks for the suggestion. I tried to add the yet another promise for it.
Will you suggest the way to extend that during the installing? |
All that might be needed is to remove the check on the event's The
|
sure. |
Resolved conflicts caused by w3c#1719
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
I think we still need to work on the in parallel/queue a task, but this can be done as part of #1742.
It would be useful to add some WPT tests:
- addRoutes after installing.
- The order of route validation might be slightly different after the PR (in case one route is invalid and the other has a fetch source but there is no registered fetch event handler).
- Call addRoutes several times and verify ordering is preserved when matching a fetch load.
Yes. WPTs will come later. @domenic Will you take another look at this? |
@monica-ch Can I ask you to take a look? |
@youennf can I ask you to clarify the followings? Or, will you show some snippets that make things different?
The PR clearly separated the verification and the update. However, a process before the PR still returns promise reject on the verify failure without updating the Stepping back, do you suggest to add WPT that failing |
@yoshisatoyanagisawa Do you have an opened chromium issue to track the code changes in chomium per the spec changes? |
Sure. I opened the issue for this: |
Also, I have updated the title because in spite of my first PR, |
This is a minor point really. What I am meaning is that, before the PR, we would do:
With the PR, it does:
In both cases, |
Got it. Yeah, TypeError will be thrown in both cases, but which one to verify first has been changed. Since this is a specification, the verification order should be mattered. I had to hone that feeling. |
SHA: b6ac20c Reason: push, by yoshisatoyanagisawa Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
SHA: b6ac20c Reason: push, by pull[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This is a fix for #1742 and #1743.
Currently, it is technically possible to call
addRoutes()
outside of the install event. This change follows howFetchEvent.respondWith()
deal with the case, and prevents theaddRoutes()
method to be called outside of the install event.At the same time, the event wait until a promise returned by
addRoutes()
resolves.Preview | Diff