-
Notifications
You must be signed in to change notification settings - Fork 1
Add race-network-and-fetch-handler option
#10
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
Changes from 14 commits
569c3de
ad5f0b9
10db402
e6e70bc
e18d7ea
210fd4f
8e087c8
2e86804
b9d6c63
67561a6
f8a0d3d
fd5b794
aa42d55
3245241
01c0773
6d43556
27ccc75
1cd657a
4765d5c
bf4bdaf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1079,7 +1079,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| }; | ||
| </pre> | ||
|
|
||
| A {{ServiceWorkerGlobalScope}} object represents the global execution context of a [=/service worker=]. A {{ServiceWorkerGlobalScope}} object has an associated <dfn export for="ServiceWorkerGlobalScope">service worker</dfn> (a [=/service worker=]). A {{ServiceWorkerGlobalScope}} object has an associated <dfn for="ServiceWorkerGlobalScope">force bypass cache for import scripts flag</dfn>. It is initially unset. | ||
| A {{ServiceWorkerGlobalScope}} object represents the global execution context of a [=/service worker=]. A {{ServiceWorkerGlobalScope}} object has an associated <dfn export for="ServiceWorkerGlobalScope">service worker</dfn> (a [=/service worker=]). A {{ServiceWorkerGlobalScope}} object has an associated <dfn for="ServiceWorkerGlobalScope">force bypass cache for import scripts flag</dfn>. A {{ServiceWorkerGlobalScope}} object has an associated <dfn for="ServiceWorkerGlobalScope">race response map</dfn> which is an [=ordered map=] where the [=map/keys=] are [=requests=] and the [=map/values=] are <a>promises</a>. It is initially unset. | ||
|
|
||
| Note: {{ServiceWorkerGlobalScope}} object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully <a>registered</a>, a [=/service worker=] is started, kept alive and killed by their relationship to events, not [=/service worker clients=]. Any type of synchronous requests must not be initiated inside of a [=/service worker=]. | ||
|
|
||
|
|
@@ -1578,7 +1578,12 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| }; | ||
|
|
||
| enum RunningStatus { "running", "not-running" }; | ||
| enum RouterSourceEnum { "cache", "fetch-event", "network" }; | ||
| enum RouterSourceEnum { | ||
| "cache", | ||
| "fetch-event", | ||
| "network", | ||
| "race-network-and-fetch-handler" | ||
| }; | ||
| </pre> | ||
|
|
||
| <section> | ||
|
|
@@ -3106,19 +3111,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| :: |controller|, a [=fetch controller=] | ||
| :: |useHighResPerformanceTimers|, a boolean | ||
| : Output | ||
| :: |response|, a [=/response=] | ||
| :: a [=/response=] | ||
|
|
||
| 1. Let |handleFetchFailed| be false. | ||
| 1. Let |respondWithEntered| be false. | ||
| 1. Let |eventCanceled| be false. | ||
| 1. Let |response| be null. | ||
| 1. Let |registration| be null. | ||
| 1. Let |client| be |request|'s [=request/client=]. | ||
| 1. Let |reservedClient| be |request|'s [=request/reserved client=]. | ||
| 1. Let |preloadResponse| be a new [=promise=]. | ||
| 1. Let |workerRealm| be null. | ||
| 1. Let |eventHandled| be null. | ||
| 1. Let |timingInfo| be a new [=service worker timing info=]. | ||
| 1. Let |raceResponse| be null. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here it would be:
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is |
||
| 1. Assert: |request|'s [=request/destination=] is not "<code>serviceworker</code>". | ||
| 1. If |request|'s [=request/destination=] is either "<code>embed</code>" or "<code>object</code>", then: | ||
| 1. Return null. | ||
|
|
@@ -3154,7 +3155,27 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| 1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns <b>blocked</b>, then return null. | ||
| 1. Return |response|. | ||
| 1. Return null. | ||
| 1. If |request| is a <a>non-subresource request</a>, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`<code>GET</code>\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] <code>fetch</code>, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then: | ||
| 1. Else if |source| is {{RouterSourceEnum/"race-network-and-fetch-handler"}}, and |request|'s [=request/method=] is \`<code>GET</code>\` then: | ||
| 1. Let |queue| be an empty [=queue=] of [=/response=]. | ||
| 1. Let |raceFetchController| be null. | ||
|
yoshisatoyanagisawa marked this conversation as resolved.
|
||
| 1. Set |raceResponse| to "<code>pending</code>". | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
| 1. Run the following substeps [=in parallel=], but [=abort when=] |controller|'s [=fetch controller/state=] is "<code>terminated</code>" or "<code>aborted</code>": | ||
| 1. Set |raceFetchController| to the result of calling [=fetch=] given |request|, with [=fetch/processResponse=] set to the following steps given a [=/response=] |raceNetworkRequestResponse|: | ||
| 1. If |raceNetworkRequestResponse|'s [=response/status=] is [=ok status=], then: | ||
| 1. Set |raceResponse| to |raceNetworkRequestResponse|. | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
| 1. [=queue/Enqueue=] |raceNetworkRequestResponse| to |queue|. | ||
|
sisidovski marked this conversation as resolved.
|
||
| 1. Otherwise, set |raceResponse| to a `TypeError`. | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
| 1. [=If aborted=] and |raceFetchController| is not null, then: | ||
|
sisidovski marked this conversation as resolved.
|
||
| 1. [=fetch controller/abort=] |raceFetchController|. | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
| 1. Set |raceResponse| to null. | ||
| 1. Resolve |preloadResponse| with undefined. | ||
| 1. Run the following substeps [=in parallel=]: | ||
| 1. Let |fetchHandlerResponse| be the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|. | ||
| 1. If |fetchHandlerResponse| is not null and not a [=network error=], and |raceFetchController| is not null, [=fetch controller/abort=] |raceFetchController|. | ||
| 1. [=queue/Enqueue=] |fetchHandlerResponse| to |queue|. | ||
| 1. Wait until |queue| is not empty. | ||
| 1. Return the result of [=dequeue=] |queue|. | ||
| 1. If |request| is a <a>non-subresource request</a>, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |request|'s [=request/method=] is \`<code>GET</code>\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] <code>fetch</code>, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set, then: | ||
|
|
||
| Note: If the above is true except |registration|'s [=active worker=]'s <a>set of event types to handle</a> **does not** contain <code>fetch</code>, then the user agent may wish to show a console warning, as the developer's intent isn't clear. | ||
|
|
||
|
|
@@ -3176,6 +3197,30 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| 1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|. | ||
| 1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|. | ||
| 1. Else, resolve |preloadResponse| with undefined. | ||
| 1. Return the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|. | ||
| </section> | ||
|
|
||
| <section algorithm> | ||
| <h3 id="create-fetch-event-and-dispatch-algorithm"><dfn>Create Fetch Event and Dispatch</dfn></h3> | ||
| : Input | ||
| :: |request|, a [=/request=] | ||
| :: |registration|, a [=/service worker registration=] | ||
| :: |useHighResPerformanceTimers|, a boolean | ||
| :: |timingInfo|, a [=service worker timing info=] | ||
| :: |workerRealm|, a [=relevant realm=] of the [=service worker/global object=] | ||
| :: |reservedClient|, a [=request/reserved client=] | ||
| :: |preloadResponse|, a [=promise=] | ||
| :: |raceResponse|, a null, "<code>pending</code>" or [=/response=] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Parameter passing in specs generally follows JavaScript-style conventions. So, you cannot modify a parameter from outside the called algorithm, once it has been passed. To get around this, create a tiny wrapper struct, with one item. Then the other algorithm can modify the struct item.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, in L3141, the state is either "pending" or [=/response=]. I'll update the map to accept "pending".
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Added a new struct and use it to the parameter, but not fully confident if this direction is correct. Let me know the usage is wrong. |
||
| : Output | ||
| :: a [=/response=] | ||
|
|
||
| 1. Let |response| be null. | ||
| 1. Let |eventCanceled| be false. | ||
|
sisidovski marked this conversation as resolved.
|
||
| 1. Let |client| be |request|'s [=request/client=]. | ||
| 1. Let |activeWorker| be |registration|'s <a>active worker</a>. | ||
| 1. Let |eventHandled| be null. | ||
| 1. Let |handleFetchFailed| be false. | ||
| 1. Let |respondWithEntered| be false. | ||
| 1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise: | ||
| * |request| is a [=non-subresource request=]. | ||
| * |request| is a [=subresource request=] and |registration| is [=stale=]. | ||
|
|
@@ -3195,6 +3240,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| 1. Else: | ||
| 1. Set |workerRealm| to the [=relevant realm=] of the |activeWorker|'s [=service worker/global object=]. | ||
| 1. Set |eventHandled| to [=a new promise=] in |workerRealm|. | ||
| 1. If |raceResponse| is not null, then: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible raceResponse will be set to a promise in step 13.4.3.1.1 of Handle Fetch, but never resolved with a response by step 13.4.3.1.2.1? Or, it will be rejected because of the fetch abort that occurs in step 13.4.4? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now it might be "pending", I think? The map does not say it is allowed to contain "pending", but maybe it should be expanded to allow that? |
||
| 1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. | ||
| 1. [=map/Set=] |map|[|request|] to |raceResponse|. | ||
| 1. [=Queue a task=] |task| to run the following substeps: | ||
| 1. Let |e| be the result of <a>creating an event</a> with {{FetchEvent}}. | ||
| 1. Let |controller| be a [=new=] {{AbortController}} object with |workerRealm|. | ||
|
|
@@ -3236,6 +3284,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| 1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|. | ||
| 2. Return a [=network error=]. | ||
| 1. If |eventHandled| is not null, then [=resolve=] |eventHandled|. | ||
| 1. If |raceResponse| is not null, then: | ||
| 1. Wait until |raceResponse| is not "<code>pending</code>" | ||
| 1. If |raceResponse| is [=/response=], return |raceResponse|. | ||
| 1. Return null. | ||
| 1. If |handleFetchFailed| is true, then: | ||
| 1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|. | ||
|
|
@@ -3873,6 +3924,27 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
| 1. Return true. | ||
| 1. Return false. | ||
| </section> | ||
|
|
||
| <section algorithm> | ||
| <h3 id="lookup-race-response-algorithm"><dfn export>Lookup Race Response</dfn></h3> | ||
|
|
||
| : Input | ||
| :: |request|, a [=request=] | ||
| : Output | ||
| :: a [=promise=]. | ||
|
|
||
| 1. If |request|'s [=request/reserved client=] is null, return null. | ||
| 1. Let |storage key| be the result of running [=obtain a storage key=] given |request|'s [=request/reserved client=]. | ||
| 1. Let |registration| be the result of running <a>Match Service Worker Registration</a> given |storage key| and |url|. | ||
| 1. If |registration| is null or |registration|'s <a>active worker</a> is null, return null. | ||
| 1. Else, let |activeWorker| be |registration|'s <a>active worker</a>. | ||
| 1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. | ||
| 1. If |map|[|request|] [=map/exist=], then: | ||
| 1. Let |entry| be |map|[|request|]. | ||
| 1. [=map/Remove=] |map|[|request|]. | ||
| 1. Return |entry|. | ||
| 1. Otherwise, return null. | ||
| </section> | ||
| </section> | ||
|
|
||
| <section> | ||
|
|
||
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 think the map values are now "response"s?
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.
"response"s or "pending"? I updated it with the new struct though.