Skip to content

Commit 9c00904

Browse files
domenicdomfarolino
andauthored
Add extended lifetime shared workers
This PR introduces extended lifetime shared workers as a lightweight alternative to e.g., Service Workers, to perform complex, async operations after document unloading. Specifically, this PR introduces the SharedWorkerOptions dictionary and its extendedLifetime boolean member. Together, they allow a SharedWorkerGlobalScope's lifetime to be extended by an implementation-defined time, when it would otherwise be suspendable. Before this, a shared worker whose owner set is empty or contains only non-fully-active owners would not be "actively needed" or "protected"; it would be thus suspendable for the duration of its https://html.spec.whatwg.org/#between-loads-shared-worker-timeout, or for as long as it has clients, respectively. This is useful for keeping the worker around for a bit so that it doesn't need to be re-initialized from scratch later, but it doesn't guarantee that the worker can perform any last-minute work in this period. Extended lifetime shared workers allow the worker to stay "actively needed" and thus not "suspendable" during the extended lifetime timeout. This ensures they keep running until the timeout expires. --------- Co-authored-by: Dominic Farolino <domfarolino@gmail.com>
1 parent bbaf8a7 commit 9c00904

1 file changed

Lines changed: 119 additions & 16 deletions

File tree

source

Lines changed: 119 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4452,6 +4452,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
44524452
<li><dfn data-x="on-fetch-request-algorithm" data-x-href="https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm">handle fetch</dfn></li>
44534453
<li><dfn data-x="scope-match-algorithm" data-x-href="https://w3c.github.io/ServiceWorker/#scope-match-algorithm">match service worker registration</dfn></li>
44544454
<li><dfn data-x="dfn-service-worker" data-x-href="https://w3c.github.io/ServiceWorker/#dfn-service-worker">service worker</dfn></li>
4455+
<li><dfn data-x-href="https://w3c.github.io/ServiceWorker/#dfn-service-worker-client">service worker client</dfn></li>
44554456
<li><dfn data-x="serviceworkercontainer-service-worker-client" data-x-href="https://w3c.github.io/ServiceWorker/#serviceworkercontainer-service-worker-client">service worker client</dfn></li>
44564457
<li><dfn data-x-href="https://w3c.github.io/service-workers/#dfn-service-worker-registration">service worker registration</dfn></li>
44574458
<li><dfn data-x-href="https://w3c.github.io/ServiceWorker/#serviceworker"><code>ServiceWorker</code></dfn> interface</li>
@@ -130786,9 +130787,10 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
130786130787
<span>origin</span>), <dfn data-x="concept-SharedWorkerGlobalScope-constructor-url">constructor
130787130788
URL</dfn> (a <span>URL record</span>), and <dfn
130788130789
data-x="concept-SharedWorkerGlobalScope-credentials">credentials</dfn> (a <span
130789-
data-x="concept-request-credentials-mode">credentials mode</span>). They are initialized when the
130790-
<code>SharedWorkerGlobalScope</code> object is created, in the <span>run a worker</span>
130791-
algorithm.</p>
130790+
data-x="concept-request-credentials-mode">credentials mode</span>), and <dfn
130791+
data-x="concept-SharedWorkerGlobalScope-extended-lifetime">extended lifetime</dfn> (a boolean).
130792+
They are initialized when the <code>SharedWorkerGlobalScope</code> object is created, in the
130793+
<span>run a worker</span> algorithm.</p>
130792130794

130793130795
</div>
130794130796

@@ -130907,13 +130909,77 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
130907130909
<p class="note">A typical value for the <span>between-loads shared worker timeout</span> might be
130908130910
5 seconds.</p>
130909130911

130912+
<p>A user agent has an <span>implementation-defined</span> value, the <dfn>extended lifetime
130913+
shared worker timeout</dfn>, which is some amount of time. This represents how long the user agent
130914+
allows shared workers which the web developer has requested be given an extended lifetime, to
130915+
survive and perform work after all of their <span data-x="owner set">owners</span> have
130916+
disappeared. User agents should choose a value that is equal to the longest lifetime that a
130917+
service worker can stay alive without any <span data-x="service worker client">clients</span>, and
130918+
must not choose a value that is longer than that amount of time.</p>
130919+
130920+
<p class="note">A typical value for the <span>extended lifetime shared worker timeout</span> could
130921+
be anywhere from 10 seconds to 5 minutes, depending on the implementation's individual policies
130922+
regarding background work being performed by an origin without a user-visible representation.</p>
130923+
130910130924
<hr>
130911130925

130926+
<div algorithm>
130927+
<p>A <code>WorkerGlobalScope</code> <var>global</var> is <dfn data-x="in extended lifetime
130928+
worker">in extended lifetime</dfn> if the following algorithm returns true:</p>
130929+
130930+
<ol>
130931+
<li><p>If <var>global</var> is not a <code>SharedWorkerGlobalScope</code>, then return
130932+
false.</p></li>
130933+
130934+
<li><p>If <var>global</var>'s <span
130935+
data-x="concept-SharedWorkerGlobalScope-extended-lifetime">extended lifetime</span> is false,
130936+
then return false.</p></li>
130937+
130938+
<li><p>If <var>global</var>'s <span>owner set</span> <span data-x="list is empty">is
130939+
empty</span>, but has been empty for less than the user agent's <span>extended lifetime shared
130940+
worker timeout</span>, then return true.</p></li>
130941+
130942+
<li>
130943+
<p><span data-x="list iterate">For each</span> <var>owner</var> of <var>global</var>'s
130944+
<span>owner set</span>:</p>
130945+
130946+
<ol>
130947+
<li>
130948+
<p>If <var>owner</var> is a <code>Document</code> that is <span>fully active</span>, then
130949+
return false:</p>
130950+
130951+
<p class="note">In this case <var>global</var> will be <span data-x="active needed
130952+
worker">actively needed</span>, but it's not in extended lifetime.</p>
130953+
</li>
130954+
</ol>
130955+
</li>
130956+
130957+
<li>
130958+
<p><span data-x="list iterate">For each</span> <var>owner</var> of <var>global</var>'s
130959+
<span>owner set</span>:</p>
130960+
130961+
<ol>
130962+
<li><p>If <var>owner</var> is a <code>Document</code> and the amount of time that
130963+
<var>owner</var> that has been non-<span>fully active</span> is less than the user agent's
130964+
<span>extended lifetime shared worker timeout</span>, then return true.</p></li>
130965+
130966+
<li><p>If <var>owner</var> is a <code>WorkerGlobalScope</code> that is <span data-x="in
130967+
extended lifetime worker">in extended lifetime</span>, then return true.</p></li>
130968+
</ol>
130969+
</li>
130970+
130971+
<li><p>Return false.</p></li>
130972+
</ol>
130973+
</div>
130974+
130912130975
<div algorithm>
130913130976
<p>A <code>WorkerGlobalScope</code> <var>global</var> is <dfn data-x="active needed
130914130977
worker">actively needed</dfn> if the following algorithm returns true:</p>
130915130978

130916130979
<ol>
130980+
<li><p>If <var>global</var> is <span data-x="in extended lifetime worker">in extended
130981+
lifetime</span>, then return true.</p></li>
130982+
130917130983
<li>
130918130984
<p><span data-x="list iterate">For each</span> <var>owner</var> of <var>global</var>'s
130919130985
<span>owner set</span>:</p>
@@ -130939,6 +131005,9 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
130939131005
<li><p>If <var>global</var> is not <span data-x="active needed worker">actively needed</span>,
130940131006
then return false.</p></li>
130941131007

131008+
<li><p>If <var>global</var> is <span data-x="in extended lifetime worker">in extended
131009+
lifetime</span>, then return true.</p></li>
131010+
130942131011
<li><p>If <var>global</var> is a <code>SharedWorkerGlobalScope</code>, then return true.</p></li>
130943131012

130944131013
<li><p>If <var>global</var>'s <span>the worker's ports</span> is not <span data-x="list is
@@ -130960,6 +131029,9 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
130960131029
<li><p>If <var>global</var>'s <span>owner set</span> is not <span data-x="list is
130961131030
empty">empty</span>, then return true.</p></li>
130962131031

131032+
<li><p>If <var>global</var> is <span data-x="in extended lifetime worker">in extended
131033+
lifetime</span>, then return true.</p></li>
131034+
130963131035
<li>
130964131036
<p>If all of the following are true:</p>
130965131037

@@ -130985,6 +131057,11 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
130985131057
<p>The following relationships hold between these terms:</p>
130986131058

130987131059
<ul>
131060+
<li><p>Every <code>WorkerGlobalScope</code> that is <span data-x="in extended lifetime
131061+
worker">in extended lifetime</span> is <span data-x="active needed worker">actively
131062+
needed</span>, <span data-x="protected worker">protected</span>, and <span data-x="permissible
131063+
worker">permissible</span>.</p></li>
131064+
130988131065
<li><p>Every <code>WorkerGlobalScope</code> that is <span data-x="active needed worker">actively
130989131066
needed</span> or <span data-x="protected worker">protected</span> is <span data-x="permissible
130990131067
worker">permissible</span>.</p></li>
@@ -131015,11 +131092,17 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
131015131092
</ul>
131016131093
</div>
131017131094

131018-
<p class="note" id="note-between-loads-shared-worker-timeout-lifetime">The <span>between-loads
131019-
shared worker timeout</span> only influences the definition of <span data-x="permissible
131020-
worker">permissible</span>, not <span data-x="protected worker">protected</span>, and so
131021-
implementations are not required to keep shared workers alive for that duration. Rather, they are
131022-
required to close shared workers after the timeout is reached.</p>
131095+
<div class="note" id="note-between-loads-shared-worker-timeout-lifetime">
131096+
<p>The <span>between-loads shared worker timeout</span> only influences the definition of <span
131097+
data-x="permissible worker">permissible</span>, not <span data-x="protected
131098+
worker">protected</span>, and so implementations are not required to keep shared workers alive
131099+
for that duration. Rather, they are required to close shared workers after the timeout is
131100+
reached.</p>
131101+
131102+
<p>In contrast, the <span>extended lifetime shared worker timeout</span> does influence the
131103+
definition of <span data-x="protected worker">protected</span>, so implementations are required
131104+
to keep shared workers alive (and not suspended) for that duration.</p>
131105+
</div>
131023131106

131024131107
<div algorithm>
131025131108
<p>A <code>WorkerGlobalScope</code> <var>global</var> is <dfn data-x="suspendable
@@ -131128,6 +131211,11 @@ interface <dfn interface>SharedWorkerGlobalScope</dfn> : <span>WorkerGlobalScope
131128131211
<li><p>Set <var>worker global scope</var>'s <span
131129131212
data-x="concept-SharedWorkerGlobalScope-credentials">credentials</span> to
131130131213
<var>options</var>["<code data-x="dom-WorkerOptions-credentials">credentials</code>"].</p></li>
131214+
131215+
<li><p>Set <var>worker global scope</var>'s <span
131216+
data-x="concept-SharedWorkerGlobalScope-extended-lifetime">extended lifetime</span> to
131217+
<var>options</var>["<code
131218+
data-x="dom-SharedWorkerOptions-extendedLifetime">extendedLifetime</code>"].</p></li>
131131131219
</ol>
131132131220
</li>
131133131221

@@ -131693,11 +131781,15 @@ enum <dfn enum>WorkerType</dfn> { "classic", "module" };
131693131781

131694131782
<pre><code class="idl">[Exposed=Window]
131695131783
interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
131696-
<span data-x="dom-SharedWorker">constructor</span>((<code data-x="tt-trustedscripturl">TrustedScriptURL</code> or USVString) scriptURL, optional (DOMString or <span>WorkerOptions</span>) options = {});
131784+
<span data-x="dom-SharedWorker">constructor</span>((<code data-x="tt-trustedscripturl">TrustedScriptURL</code> or USVString) scriptURL, optional (DOMString or <span>SharedWorkerOptions</span>) options = {});
131697131785

131698131786
readonly attribute <span>MessagePort</span> <span data-x="dom-SharedWorker-port">port</span>;
131699131787
};
131700-
<span>SharedWorker</span> includes <span>AbstractWorker</span>;</code></pre>
131788+
<span>SharedWorker</span> includes <span>AbstractWorker</span>;
131789+
131790+
dictionary <dfn dictionary>SharedWorkerOptions</dfn> : <span>WorkerOptions</span> {
131791+
boolean <dfn dict-member for="SharedWorkerOptions" data-x="dom-SharedWorkerOptions-extendedLifetime">extendedLifetime</dfn> = false;
131792+
};</code></pre>
131701131793

131702131794
<dl class="domintro">
131703131795
<dt><code data-x=""><var>sharedWorker</var> = new <span subdfn data-x="dom-SharedWorker">SharedWorker</span>(<var>scriptURL</var> [, <var>name</var> ])</code></dt>
@@ -131725,11 +131817,17 @@ interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
131725131817
<li><p><code data-x="dom-WorkerOptions-credentials">credentials</code> can be used to specify
131726131818
how <var>scriptURL</var> is fetched, but only if <code
131727131819
data-x="dom-WorkerOptions-type">type</code> is set to "<code data-x="">module</code>".</p></li>
131820+
131821+
<li><p><code data-x="dom-SharedWorkerOptions-extendedLifetime">extendedLifetime</code> can be
131822+
set to request that the newly-created global environment be given extra time to perform its
131823+
operations even after all of its <span data-x="owner set">owners</span> have disappeared. This
131824+
can be useful, for example, for performing asynchronous work after page unload.</p></li>
131728131825
</ul>
131729131826

131730-
<p>Note that attempting to construct a shared worker with <var>options</var> whose <code
131731-
data-x="dom-WorkerOptions-type">type</code>, or <code
131732-
data-x="dom-WorkerOptions-credentials">credentials</code> values mismatch those
131827+
<p class="warning">Note that attempting to construct a shared worker with <var>options</var>
131828+
whose <code data-x="dom-WorkerOptions-type">type</code>, <code
131829+
data-x="dom-WorkerOptions-credentials">credentials</code>, or <code
131830+
data-x="dom-SharedWorkerOptions-extendedLifetime">extendedLifetime</code> values mismatch those
131733131831
of an existing shared worker with the same <span
131734131832
data-x="concept-SharedWorkerGlobalScope-constructor-url">constructor URL</span> and <span
131735131833
data-x="concept-WorkerGlobalScope-name">name</span>, will cause the returned
@@ -131880,12 +131978,17 @@ interface <dfn interface>SharedWorker</dfn> : <span>EventTarget</span> {
131880131978
<ul>
131881131979
<li><p><var>workerGlobalScope</var>'s <span
131882131980
data-x="concept-WorkerGlobalScope-type">type</span> is not equal to <var>options</var>["<code
131883-
data-x="dom-WorkerOptions-type">type</code>"]; or</p></li>
131981+
data-x="dom-WorkerOptions-type">type</code>"];</p></li>
131884131982

131885131983
<li><p><var>workerGlobalScope</var>'s <span
131886131984
data-x="concept-SharedWorkerGlobalScope-credentials">credentials</span> is not equal to
131887-
<var>options</var>["<code
131888-
data-x="dom-WorkerOptions-credentials">credentials</code>"]</p></li>
131985+
<var>options</var>["<code data-x="dom-WorkerOptions-credentials">credentials</code>"];
131986+
or</p></li>
131987+
131988+
<li><p><var>workerGlobalScope</var>'s <span
131989+
data-x="concept-SharedWorkerGlobalScope-extended-lifetime">extended lifetime</span> is not
131990+
equal to <var>options</var>["<code
131991+
data-x="dom-SharedWorkerOptions-extendedLifetime">extendedLifetime</code>"],</p></li>
131889131992
</ul>
131890131993

131891131994
<p>then:</p>

0 commit comments

Comments
 (0)