-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Improve navigate for service worker hooks #1776
Conversation
This patch fixes the client matching flow and exposes reserved client and target client information by adding necessary hooks to fetch and HTML. Related issue: #870 Call flow: #870 (comment) Expected behavior: #870 (comment) Related changes: - HTML: whatwg/html#1776 - Fetch: whatwg/fetch#383 * Work on Handle Fetch is done. Work on the client API is in progress.
@annevk, I put together the changes based on the outline here:
I'd appreciate your review. |
Note for others interested in this PR, we're discussing the general design in whatwg/fetch#383. |
df5262b
to
8019b32
Compare
8019b32
to
adda326
Compare
This patch defines request's reserved client id and target client id that are set to a reserved environment's id and the target browsing context's active document's settings object's id respectively during a navigation. The given values are primarily used to provide the reserved client's id and target client's id to service workers' fetch event handlers. Related issue: w3c/ServiceWorker#870 Call flow: w3c/ServiceWorker#870 (comment) Expected behavior: w3c/ServiceWorker#870 (comment) Related changes: - HTML: whatwg/html#1776 - SW (WIP): w3c/ServiceWorker@df39d89
@annevk, I basically regarded the environment concept and the environment settings object concept are covariant. So, I defined it as "an environment settings object is an environment." and later in the service worker, I'll use the environment to enumerate all the clients there. Please take a look. |
Self-note: |
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 looks like an improvement though the editorial changes are a little distracting.
I'm also a little unsure about naming. We have "environment settings object" which effectively means global object. This adds "environment" which means something like "future/reserved global object".
It's also a little weird still that we grab some state from request to create something new and then grab something from the newly created thing and tack it on request. That just doesn't seem quite right.
optional opaque string <var>reservedId</var>, it must run the following steps:</p> | ||
|
||
<ol> | ||
<li><p>If <var>reservedId</var> is present, set <var>settingsObject</var>'s <span>id</span> to |
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.
<span>id</span>
probably needs data-x
?
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.
Done.
<p>Return <var>execution context</var>.</p> | ||
|
||
</dd> | ||
<dd><p>Return <var>executionContext</var>.</p></dd> |
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 like this kind of cleanup, but @domenic needs to approve it. Also, it might be better to do that in a separate editorial-changes-only commit.
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'll follow what you and @domenic guide here.
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.
Yes, let's please remove the reflowing of paragraphs/deleting of blank lines/renaming of variables from this commit.
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.
Done.
|
||
<li><p>Set <var>request</var>'s <span data-x="concept-request-reserved-client-id">reserved | ||
client id</span> to <var>reservedEnvironment</var>'s <span | ||
data-x="concept-environment-id">id</span>.</p></li> |
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 don't really understand this. If we create the environment here, doesn't it need to be passed along with the request? Or is the idea that we later find it again through its id?
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.
That'd be an option, but I think fetch already has the other states on the request already: the url and the target browsing context.
What service worker needs during dispatching the fetch event is the reserved environment's id to set FetchEvent.reservedClientId
. And yes, the idea is to let the fetch event handler get the client using e.g. clients.get(e.reservedClientId)
.
In the similar reason, I proposed adding a target client id internal slot to request, too: whatwg/fetch@4511e2e As discussed during the f2f, we wanted to capture the target client's id here instead of crossing the process border later when the service worker needs to access the target client in the fetch event dispatch steps.
@@ -82253,15 +82263,14 @@ State: <OUTPUT NAME=I>1</OUTPUT> <INPUT VALUE="Increment" TYPE=BUTTON O | |||
</li> | |||
|
|||
<li><p>Run <span>process a navigate response</span> given <var>request</var>, | |||
<var>response</var>, <var>navigationType</var>, the <span>source browsing context</span>, and | |||
<var>browsingContext</var>.</p></li> | |||
<var>response</var>, <var>navigationType</var>, the <span>source browsing context</span>, <var>browsingContext</var>, and <var>reservedEnvironment</var>.</p></li> |
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.
The wrapping here seems wrong.
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.
Fixed.
Open to renaming it. I absolutely want a better name for it if we can get one.
I don't think I can help here. The only state I copy from request to environment is the request's url which the newly created environment has to have. (Note that I tried to factor the creation URL out to environment as both environment and environment settings object need this info.) And the only state I copy from the created environment to request is its id, which is the whole idea this patch suggests. I think it makes sense as a navigation works in this way. |
Are you saying that this is also how Chrome/Samsung Internet would engineer this setup? @wanderview would we use this setup in Firefox? |
I'll dig into it again, but this is what I found sometime ago: #322 (comment) Basically, Chromium will have to implement something similar to the reserved id, store it somewhere like in the service worker provider and later relate the id to the actual frame id when the frame and the document are created. So, I think, in order to expose the Also, I'd appreciate your comments on calling the match service worker registration algorithm twice: once for main resource fetch and the other for attaching a controller after the global is created. This is due to the fact that it's not easy to pass the captured state around between navigate/fetch/SW. |
Having thought a bit more on this, matching the registration twice is awkward. I think we can do better as we now have the environment concept where we can store the matched registration. For this, we'd have to pass this environment along with the request as @annevk asked above. So, the idea is:
(With this change, we don't need to store the active worker on the global objects. Also, by passing the environment along with a request, we can remove request's target browsing context internal slot. We can use reserved client's target browsing context instead.) For worker clients, we can basically do the same and will pass the entire environment settings object (instead of an environment) that is set with the matched registration to fetch. This means the type of "reserved client" internal slot to request should be "null or an environment or an environment settings object". I think this matches the implementations more precisely, at least Chromium. @wanderview, would it make sense for Gecko? (Note that this doesn't change the originally proposed behavior in this PR. Both matching the registration twice and matching it once / storing in an environment will use the latest active worker always.) |
Having reviewed Chromium's navigation part of the code again, I believe the structure I'm trying to spec in this PR would be implementable. The current implementation is explained in #322 (comment) The gist is when it initializes the request handler for a navigation request ( So for navigation requests, Chromium will need to change to set the request handler's provider_host to the source client instead of the reserved client. And add a reserved_provider_host or similar state to grab the pre-created (i.e. reserved) client and the target_provider_host's client_id. Still would like to check what Gecko does and whether the proposed structure is implementable there. |
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 needs to be rebased and also the build fails due to a parsing error, so I am not quite able to review the output. Reviewing will be much easier after the editorial changes are removed too.
Overall I am pretty happy with this direction though. The environment + environment settings object concept makes sense. We should think harder to see if there is a better name, but we can leave that for a bit later.
@@ -77994,12 +78001,31 @@ console.assert(iframeWindow.frameElement === null); | |||
|
|||
<h4>Script settings for browsing contexts</h4> | |||
|
|||
<p>When the user agent is required to <dfn>set up an environment</dfn>, given an |
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.
Since this is browsing context specific, then it should probably have that in the name, like "set up a browsing context environment settings object" does. So "set up a browsing context environment".
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.
Indeed this algorithm isn't browsing context specific. It's invoked from both set up a browsing context environment settings object and set up a worker environment settings object. I think this algorithm definition needs to move to a better place?
optional opaque string <var>reservedId</var>, it must run the following steps:</p> | ||
|
||
<ol> | ||
<li><p>If <var>reservedId</var> is present, set <var>settingsObject</var>'s <span |
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.
s/is present/is given/
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.
Done.
<p>Return <var>execution context</var>.</p> | ||
|
||
</dd> | ||
<dd><p>Return <var>executionContext</var>.</p></dd> |
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.
Yes, let's please remove the reflowing of paragraphs/deleting of blank lines/renaming of variables from this commit.
@@ -78487,6 +78483,16 @@ callback <dfn>FrameRequestCallback</dfn> = void (<span>DOMHighResTimeStamp</span | |||
http://lxr.mozilla.org/mozilla/source/dom/public/idl/base/nsIDOMWindowInternal.idl - DOM level 0 | |||
--> | |||
|
|||
<p>A <code>Window</code> object has an <dfn data-export="" |
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.
Why move this? I think it should stay where it is (in the w-nodev div) and the active worker should also go there.
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 thought it would've been more consistent to other part of the spec such as WorkerGlobalScope definition where the internal slots are defined before the method/attribute description section. But I found it's not very consistent across the document. Reverted this line. (Note that active worker isn't defined in the global object any long, so it's removed here.)
|
||
<p>A <code>Window</code> object has an associated <dfn data-export="" data-dfn-for="Window" | ||
data-x="concept-Window-active-worker">active worker</dfn> (null or a <span | ||
data-x="dfn-service-worker">service worker</span>). It is initially null.</p> |
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.
We should call this "active service worker"; it is quite confusing to me otherwise.
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 state has been moved to the environment concept. So, it's called environment's service worker now. Not sure whether "active service worker" would be a better name though. This internal slot basically holds the value of either null or a service worker in "active" state only.
<ol> | ||
<li><p>Let <var>registration</var> be the result of running <span | ||
data-x="scope-match-algorithm">match service worker registration</span> with the | ||
<code>Document</code>’s <span>URL</span>.</p></li> |
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.
No curly quotes
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.
Addressed. Thanks for spotting.
Thanks @domenic. I'll address your comments and this change (#1776 (comment)) after checking with @wanderview if Gecko has any concerns. |
@wanderview, I'd like to check with you this spec change is feasible with Gecko. I'd appreciate your comments on the below questions. Gecko's using a document id to identify a client. It generates a new document id in
|
This patch fixes the client matching flow and exposes reserved client and target client information by adding necessary hooks to fetch and HTML. Related issue: #870 Call flow: #870 (comment) Expected behavior: #870 (comment) Related changes: - HTML: whatwg/html#1776 - Fetch: whatwg/fetch#383 * Work on Handle Fetch is done. Work on the client API is in progress.
Had a chat with @wanderview. We agreed to proceed with this PR. I'll address the comments given so far and the changes outlined in #1776 (comment), and ask review. |
Before this patch, we didn't have a concept that holds reserved client's information referenced from a service worker during a navigation (more precisely before the actual global object and its relevant environment settings object for the resulting resource is created). This patch defines an "environment" concept (a supertype object of an environment settings object) that has its id, creation URL and target browsing context such that service workers' FetchEvent hanlder can reference this client information before the corresponding environmet setings object is actually created. The changes include: - Create an environment (a reserved client) during a navigation - Set request's reserved client id such that fetch (and Handle Fetch) can use it - Set request's target client id such that fetch (and Handle Fetch) can use it - Add Window object's active worker internal slot - Add WorkerGlobalObject's active worker internal slot - Add "match service worker registration" logic to attach controller Related issue: w3c/ServiceWorker#870 Call flow: w3c/ServiceWorker#870 (comment) Expected behavior: w3c/ServiceWorker#870 (comment) Related changes: - SW (WIP): w3c/ServiceWorker@df39d89 - Fetch: whatwg/fetch#383
Destroy the reserved environment after setting its states to the corresponding environment settings object that is created and used for the resulting resource.
</li> | ||
|
||
<li><p>Otherwise, set <var>settings object</var>'s <span | ||
data-x="concept-environment-id">id</span> to a new unique opaque string, <var>settings |
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.
Do we expose these strings somewhere? Perhaps we should define the "opaque" format in that case. Not having that defined turned out to be a problem before (with blob URLs).
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.
Yes, we do. FetchEvent's clientId/reservedClientId/targetClientId and Client's id should return the values of this type. We used the UUID at the beginning but changed to not mandate the UUID type. Here's a discussion on this: w3c/ServiceWorker#647 And also I think we're now doing what you filed here: w3c/ServiceWorker#643
By the way, is there any reference that I can base the work on?
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 don't think so. What might be problematic is if folks start assuming the string is UTF-8-safe or even ASCII-safe, depending on what user agents do. Is it an option to return something other than a string that can only be used to check for object identity? E.g., a symbol?
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.
only be used to check for object identity
FWIW, I think this is the only purpose of the id itself. I don't think I'm familiar with what you meant by a symbol, though. Could you explain more? Would it be shown as just a string to JS?
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.
As a Symbol: https://tc39.github.io/ecma262/#sec-symbol-objects. They're somewhat more opaque than strings so might be more suitable here. Not a 100% sure though and it also depends a bit on what happens with the ID.
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.
Symbol doesn't work great across realms, without basically giving it a string name (like "Symbol.iterator"
) in which case we're back to strings. String is probably the best we'll be able to do.
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 these IDs are meant to work across realms, that makes sense.
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.
Yes, IDs are values that can be shared across realms. Symbol.for("stringkey")
wouldn't help much here.
<p class="note">The created environment's <span | ||
data-x="concept-environment-active-service-worker">active service worker</span> is set in the | ||
<span data-x="on-fetch-request-algorithm">handle fetch</span> algorithm during the subsequent | ||
fetch flow if its <span data-x="concept-environment-creation-url">creation URL</span> matches a |
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'm not sure what subsequent fetch flow is. Do you mean "during the fetch"?
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.
Yes, I meant "during the fetch". Will change it to "during the fetch".
@@ -3866,10 +3868,14 @@ a.setAttribute('href', 'http://example.com/'); // change the content attribute d | |||
<p>The following terms are defined in <cite>Service Workers</cite>: <ref spec="SW"></p> | |||
|
|||
<ul class="brief"> | |||
<li><dfn data-x="dfn-active-worker" data-x-href="https://w3c.github.io/ServiceWorker/#dfn-active-worker">active worker</dfn></li> | |||
<li><dfn data-x="dfn-client-message-queue" data-x-href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#dfn-client-message-queue">client message queue</dfn></li> |
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 we land this PR first before the other PR I wrote where I update links we should also update this link here.
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.
Addressed.
current or potential execution environment. An <span>environment</span> has the following | ||
fields:</p> | ||
|
||
<dl> |
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.
Since this is a new <dl>
I feel like we should remove a whole bunch of whitespace. E.g., when <dd>
only contains a single <p>
it can be all together. No newline between <dt>
and <dd>
, only between <dd>
and <dt>
. What do you think?
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.
Referencing the contributing.md,
If a "block" element contains a single "block" element, do not put it on a newline. Do not indent for anything except a new "block" element.
I think that makes sense for new works and changed them as such.
<dd> | ||
|
||
<p>null or a target <span>browsing context</span> for a <span | ||
data-x="navigation-request">navigation request</span>.</p> |
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 should say "Null" I think. We don't start with a lowercase letter in these <dd>
s anywhere else either. Same for below.
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.
Done.
LGTM with those last few nits fixed. I assume we don't have a testing plan here because this is is about new stuff? That's probably okay. |
@annevk, I uploaded a new snapshot having addressed those comments. Please take a look. |
I'm going to merge this now and then work with @jungkees today/tomorrow to get the corresponding change to Fetch landed as soon as possible. Either way there'll be some broken URLs. |
Actually, @jungkees could you write a new commit message perhaps? |
@annevk, I'm not sure but presume you'll squash all the commits to a single commit, right? I have no idea if I can amend any commit message myself, so I updated the commit message in the OP. Let me know if I can help in another way. |
This patch defines request's reserved client id and target client id that are set to a reserved environment's id and the target browsing context's active document's settings object's id respectively during a navigation. The given values are primarily used to provide the reserved client's id and target client's id to service workers' fetch event handlers. Related issue: w3c/ServiceWorker#870 Call flow: w3c/ServiceWorker#870 (comment) Expected behavior: w3c/ServiceWorker#870 (comment) Related changes: - HTML: whatwg/html#1776 - SW (WIP): w3c/ServiceWorker@df39d89
This patch defines the request's reserved client and the target client id. The reserved client of a request is set to an environment or an environment settings object during a navigation or a worker creation request, respectively. The target client id of a request is set to the target browsing context's active document's environment settings object's id during a navigation. The given values are primarily used to provide the reserved client's id and target client's id to service workers' fetch event handlers. This removes the request's target browsing context as the reserved client provides the same information. Related issue: w3c/ServiceWorker#870 Related change: whatwg/html#1776
Thanks for writing it! 😊 |
This patch defines the request's reserved client and the target client id. The reserved client of a request is set to an environment or an environment settings object during a navigation or a worker creation request, respectively. The target client id of a request is set to the target browsing context's active document's environment settings object's id during a navigation. The given values are primarily used to provide the reserved client's id and target client's id to service workers' fetch event handlers. This removes the request's target browsing context as the reserved client provides the same information. Related issue: w3c/ServiceWorker#870 Related change: whatwg/html#1776
This patch defines the request's reserved client and the target client id. The reserved client of a request is set to an environment or an environment settings object during a navigation or a worker creation request, respectively. The target client id of a request is set to the target browsing context's active document's environment settings object's id during a navigation. The given values are primarily used to provide the reserved client's id and target client's id to service workers' fetch event handlers. This removes the request's target browsing context as the reserved client provides the same information. Related issue: w3c/ServiceWorker#870 Related change: whatwg/html#1776
2b93f9e (PR whatwg#1776) introduced a minor markup error (an `ol` nested inside an `ol`). This fixes it.
This makes browsing context's active document a getter, returning browsing context's WindowProxy object's [[Window]] internal slot's associated Document. This removes some service worker text that was added in whatwg#1776. Reinstating that in some manner is whatwg#2687. Fixes whatwg#2657, fixes whatwg#2676.
Improve navigate for service worker hooks
Before this patch, there has been no concept that holds reserved
client's information referenced from a service worker during a
navigation (more precisely before the actual global object and its
relevant environment settings object for the resulting resource is
created).
This patch defines an "environment" concept (a supertype object of an
environment settings object) that has an id, a creation URL, a target
browsing context, and an active service worker such that service
workers' FetchEvent hanlders can reference this client information
before the corresponding environmet setings object is actually
created.
The changes include:
worker creation requests, create an environment settings object and
set the fields correspondingly
environment settings object such that fetch (and Handle Fetch) can
use it
can use it
available, during the fetch (in service worker's Handle Fetch
algorithm).
Related issue: w3c/ServiceWorker#870
Related change: whatwg/fetch#383