Skip to content

Commit bcddf41

Browse files
domenicmfreed7
authored andcommitted
Editorial: expose "run steps after a timeout"
This factors out a new algorithm which can be used by postTask() (https://wicg.github.io/scheduling-apis/#schedule-a-posttask-task) and AbortSignal.timeout() (whatwg/dom#1032), ensuring that they correctly contribute to idle deadline computation and in general share all the appropriate logic with setTimeout() and setInterval(). This also exports the "timer task source" term since AbortSignal.abort() will want to use that.
1 parent 4d1a90b commit bcddf41

File tree

1 file changed

+91
-50
lines changed

1 file changed

+91
-50
lines changed

source

+91-50
Original file line numberDiff line numberDiff line change
@@ -93968,7 +93968,7 @@ import "https://example.com/foo/../module2.mjs";</code></pre>
9396893968
</ol>
9396993969
</li>
9397093970

93971-
<li>
93971+
<li id="idle-deadline-computation">
9397293972
<p>If all of the following are true
9397393973

9397493974
<ul class="brief">
@@ -96460,12 +96460,21 @@ enum <dfn enum>DOMParserSupportedType</dfn> {
9646096460

9646196461
<div w-nodev>
9646296462

96463-
<p>Objects that implement the <code>WindowOrWorkerGlobalScope</code> mixin have a <dfn
96464-
export>map of active timers</dfn>, which is a <span>map</span>, initially empty. Each
96465-
<span data-x="map key">key</span> in this map is identified by a number, which must be unique
96466-
within the list for the lifetime of the object that implements the
96467-
<code>WindowOrWorkerGlobalScope</code> mixin, and each <span data-x="map value">value</span> is a
96468-
<code>DOMHighResTimeStamp</code>, representing the expiry time for that timer.</p>
96463+
<p>Objects that implement the <code>WindowOrWorkerGlobalScope</code> mixin have a <dfn>map of
96464+
active timers</dfn>, which is a <span>map</span>, initially empty. Each <span data-x="map
96465+
key">key</span> in this map is an identifier for a timer, and each <span data-x="map
96466+
value">value</span> is a <code>DOMHighResTimeStamp</code>, representing the expiry time for that
96467+
timer.</p>
96468+
96469+
<p class="note">For entries put in the <span>map of active timers</span> by the <span>timer
96470+
initialization steps</span>, i.e., by <code data-x="dom-setTimeout">setTimeout()</code> and <code
96471+
data-x="dom-setInterval">setInterval()</code>, the keys are numbers. For other specifications
96472+
that use the <span>run steps after a timeout</span> algorithm, the identifier is a unique
96473+
non-numeric value. Only the numeric-keyed timers are affected by <code
96474+
data-x="dom-clearTimeout">clearTimeout()</code> and <code
96475+
data-x="dom-clearInterval">clearInterval()</code>, but all timers contribute to <a
96476+
href="#idle-deadline-computation">idle deadline computation</a>, and are cleared when the
96477+
relevant global is destroyed.</p>
9646996478

9647096479
<hr>
9647196480

@@ -96508,8 +96517,8 @@ enum <dfn enum>DOMParserSupportedType</dfn> {
9650896517

9650996518
<li><p>If <var>previousId</var> was given, let <var>id</var> be <var>previousId</var>;
9651096519
otherwise, let <var>id</var> be an <span>implementation-defined</span> integer that is greater
96511-
than zero that will identify the timeout to be set by this call in <var>global</var>'s <span>map
96512-
of active timers</span>.</p></li>
96520+
than zero and does not already <span data-x="map exists">exist</span> in <var>global</var>'s
96521+
<span>map of active timers</span>.</p></li>
9651396522

9651496523
<li>
9651596524
<p>If the <span>surrounding agent</span>'s <span data-x="concept-agent-event-loop">event
@@ -96623,50 +96632,19 @@ enum <dfn enum>DOMParserSupportedType</dfn> {
9662396632

9662496633
<li><p>Set <var>task</var>'s <dfn>timer nesting level</dfn> to <var>nesting level</var>.</p></li>
9662596634

96626-
<li><p>Let <var>startTime</var> be the <span>current high resolution time</span>.</p></li>
96627-
96628-
<li><p><span data-x="map set">Set</span> <var>global</var>'s <span>map of active
96629-
timers</span>[<var>id</var>] to <var>startTime</var> plus <var>timeout</var>.</p></li>
96635+
<li><p>Let <var>completionStep</var> be an algorithm step which <span data-x="queue a global
96636+
task">queues a global task</span> on the <dfn export>timer task source</dfn> given
96637+
<var>global</var> to run <var>task</var>.</p></li>
9663096638

9663196639
<li>
96632-
<p>Run the following steps <span>in parallel</span>:</p>
96633-
96634-
<ol>
96635-
<li>
96636-
<p>If <var>global</var> is a <code>Window</code> object, wait until <var>global</var>'s <span
96637-
data-x="concept-document-window">associated <code>Document</code></span> has been <span>fully
96638-
active</span> for a further <var>timeout</var> milliseconds (not necessarily
96639-
consecutively).</p>
96640-
96641-
<p>Otherwise, <var>global</var> is a <code>WorkerGlobalScope</code> object; wait
96642-
until <var>timeout</var> milliseconds have passed with the worker not suspended (not
96643-
necessarily consecutively).</p>
96644-
</li>
96645-
96646-
<li><p>Wait until any invocations of this algorithm that had the same <var>global</var>, that
96647-
started before this one, and whose <var>timeout</var> is equal to or less than this one's,
96648-
have completed.</p></li>
96649-
96650-
<li>
96651-
<p>Optionally, wait a further <span>implementation-defined</span> length of time.</p>
96652-
96653-
<p class="note">This is intended to allow user agents to pad timeouts as needed to optimize
96654-
the power usage of the device. For example, some processors have a low-power mode where the
96655-
granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
96656-
this schedule instead of requiring the processor to use the more accurate mode with its
96657-
associated higher power usage.</p>
96658-
</li>
96640+
<p><span>Run steps after a timeout</span> given <var>global</var>, "<code
96641+
data-x="">setTimeout/setInterval</code>", <var>timeout</var>, <var>completionStep</var>, and
96642+
<var>id</var>.</p>
9665996643

96660-
<li>
96661-
<p><span>Queue a global task</span> on the <dfn>timer task source</dfn> given
96662-
<var>global</var> to run <var>task</var>.</p>
96663-
96664-
<p class="note">Once the task has been processed, if <var>repeat</var> is false, it is safe
96665-
to remove the entry for <var>id</var> from the <span>map of active timers</span> (there is no
96666-
way for the entry's existence to be detected past this point, so it does not technically
96667-
matter one way or the other).</p>
96668-
</li>
96669-
</ol>
96644+
<p class="note">Once the task has been processed, if <var>repeat</var> is false, it is safe to
96645+
remove the entry for <var>id</var> from the <span>map of active timers</span> (there is no way
96646+
for the entry's existence to be detected past this point, so it does not technically matter one
96647+
way or the other).</p>
9667096648
</li>
9667196649

9667296650
<li><p>Return <var>id</var>.</p></li>
@@ -96718,6 +96696,69 @@ function scheduleWork() {
9671896696
scheduleWork(); // queues a task to do lots of work</code></pre>
9671996697
</div>
9672096698

96699+
<div w-nodev>
96700+
96701+
<p>To <dfn export>run steps after a timeout</dfn>, given a <code>WindowOrWorkerGlobalScope</code>
96702+
<var>global</var>, a string <var>orderingIdentifier</var>, a number <var>milliseconds</var>, a
96703+
set of steps <var>completionSteps</var>, and an optional value <var>timerKey</var>:</p>
96704+
96705+
<ol>
96706+
<li><p>Assert: if <var>timerKey</var> is given, then the caller of this algorithm is the
96707+
<span>timer initialization steps</span>. (Other specifications must not pass
96708+
<var>timerKey</var>.)</p></li>
96709+
96710+
<li><p>If <var>timerKey</var> is not given, then set it to a new unique non-numeric
96711+
value.</p></li>
96712+
96713+
<li><p>Let <var>startTime</var> be the <span>current high resolution time</span>.</p></li>
96714+
96715+
<li><p><span data-x="map set">Set</span> <var>global</var>'s <span>map of active
96716+
timers</span>[<var>timerKey</var>] to <var>startTime</var> plus
96717+
<var>milliseconds</var>.</p></li>
96718+
96719+
<li>
96720+
<p>Run the following steps <span>in parallel</span>:</p>
96721+
96722+
<ol>
96723+
<li>
96724+
<p>If <var>global</var> is a <code>Window</code> object, wait until <var>global</var>'s <span
96725+
data-x="concept-document-window">associated <code>Document</code></span> has been <span>fully
96726+
active</span> for a further <var>milliseconds</var> milliseconds (not necessarily
96727+
consecutively).</p>
96728+
96729+
<p>Otherwise, <var>global</var> is a <code>WorkerGlobalScope</code> object; wait until
96730+
<var>milliseconds</var> milliseconds have passed with the worker not suspended (not
96731+
necessarily consecutively).</p>
96732+
</li>
96733+
96734+
<li><p>Wait until any invocations of this algorithm that had the same <var>global</var> and
96735+
<var>orderingIdentifier</var>, that started before this one, and whose <var>milliseconds</var>
96736+
is equal to or less than this one's, have completed.</p></li>
96737+
96738+
<li>
96739+
<p>Optionally, wait a further <span>implementation-defined</span> length of time.</p>
96740+
96741+
<p class="note">This is intended to allow user agents to pad timeouts as needed to optimize
96742+
the power usage of the device. For example, some processors have a low-power mode where the
96743+
granularity of timers is reduced; on such platforms, user agents can slow timers down to fit
96744+
this schedule instead of requiring the processor to use the more accurate mode with its
96745+
associated higher power usage.</p>
96746+
</li>
96747+
96748+
<li><p>Perform <var>completionSteps</var>.</p></li>
96749+
</ol>
96750+
</li>
96751+
</ol>
96752+
96753+
<p class="note"><span>Run steps after a timeout</span> is meant to be used by other
96754+
specifications that want to execute developer-supplied code after a developer-supplied timeout,
96755+
in a similar manner to <code data-x="dom-setTimeout">setTimeout()</code>. (Note, however, it does
96756+
not have the nesting and clamping behavior of <code data-x="dom-setTimeout">setTimeout()</code>.)
96757+
Such specifications can choose an <var>orderingIdentifier</var> to ensure ordering within their
96758+
specification's timeouts, while not constraining ordering with respect to other specification's
96759+
timeouts.</p>
96760+
96761+
</div>
9672196762

9672296763
<h3>Microtask queuing</h3>
9672396764

0 commit comments

Comments
 (0)