-
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 17 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,9 @@ 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 [=race response=]. It is initially unset. | ||
|
|
||
| A <dfn id="dfn-race-response">race response</dfn> is a [=struct=] used to contain the network response when {{RouterSourceEnum/"race-network-and-fetch-handler"}} performs. It has a <dfn for="race response">value</dfn>, which is a [=/response=], "<code>pending</code>", or null. | ||
|
|
||
| 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 +1580,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 +3113,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 a [=race response=] whose [=race response/value=] is null. | ||
| 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 +3157,28 @@ 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|'s [=race response/value=] to "<code>pending</code>". | ||
| 1. [=map/Set=] |activeWorker|'s [=service worker/global object=]'s [=race response map=][|request|] to |raceResponse|. | ||
|
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. It might be simpler if the race response map is associates with activeWorker (i.e. a service worker) rather than its global scope? Especially as at this point in the algorithm the worker hasn't been started yet, so global object might very well be null.
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. That's a good point. How about keep the global scope having the map, and move this [=map/set=] to the step 16.2 in Create Fetch Event and Dispatch? At this point, Run Service Worker was already called to we can expect the global object is ready.
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. Updated as above. Let me know if this doesn't solve your concern. |
||
| 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|'s [=race response/value=] to |raceNetworkRequestResponse|. | ||
| 1. [=queue/Enqueue=] |raceNetworkRequestResponse| to |queue|. | ||
|
sisidovski marked this conversation as resolved.
|
||
| 1. Otherwise, set |raceResponse|'s [=race response/value=] to a [=network error=]. | ||
| 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 a [=race response=] whose [=race response/value=] is 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,9 +3200,34 @@ 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 [=race response=] | ||
| : 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=]. | ||
| 1. Let |raceResponseMap| be |activeWorker|'s [=service worker/global object=]'s [=race response map=]. | ||
| 1. If the result of running the [=Should Skip Event=] algorithm with "fetch" and |activeWorker| is true, then: | ||
| 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. | ||
| 1. Return null. | ||
|
|
@@ -3231,11 +3280,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ | |
|
|
||
| 1. Wait for |task| to have executed or for |handleFetchFailed| to be true. | ||
| 1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|. | ||
| 1. If |raceResponseMap|[|request|] [=map/exists=], [=map/remove=] |raceResponseMap|[|request|]. | ||
|
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. This step is needed to remove the map entry, which is not consumed by Fetch. The fetch handler may not have |
||
| 1. If |respondWithEntered| is false, then: | ||
| 1. If |eventCanceled| is true, then: | ||
| 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|'s [=race response/value=] is not null, then: | ||
| 1. Wait until |raceResponse|'s [=race response/value=] is not "<code>pending</code>" | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
| 1. If |raceResponse|'s [=race response/value=] is [=/response=], return |raceResponse|'s [=race response/value=]. | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
| 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 +3926,28 @@ 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 [=/response=], or null. | ||
|
sisidovski marked this conversation as resolved.
Outdated
|
||
|
|
||
| 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/exists=], then: | ||
| 1. Let |entry| be |map|[|request|]. | ||
| 1. [=map/Remove=] |map|[|request|]. | ||
| 1. Wait until |entry|'s [=race response/value=] is not "<code>pending</code>" | ||
| 1. If |entry|'s [=race response/value=] is [=/response=], return |entry|'s [=race response/value=]. | ||
| 1. Return null. | ||
| </section> | ||
| </section> | ||
|
|
||
| <section> | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.