Skip to content

Instantly share code, notes, and snippets.

@shs96c
Created September 20, 2019 04:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shs96c/108f5313eae54b94658ee018e37926d2 to your computer and use it in GitHub Desktop.
Save shs96c/108f5313eae54b94658ee018e37926d2 to your computer and use it in GitHub Desktop.
diff --git a/index.html b/index.html
index f04ea5d..72c8d86 100644
--- a/index.html
+++ b/index.html
@@ -188,6 +188,10 @@ <h2>Terminology</h2>
An <dfn>integer</dfn> is a <a>Number</a> that is unchanged
under the <a>ToInteger</a> operation.
+<p>A <dfn>millisecond timestamp</dfn> is an <a>Integer</a> that
+ approximates the number of milliseconds that have elapsed since the
+ <a>Unix Epoch</a>.
+
<p>
The <dfn>initial value</dfn> of an ECMAScript property
is the value defined by the platform for that property,
@@ -669,6 +673,30 @@ <h3>Endpoints</h3>
<td><a>New Session</a></td>
</tr>
+ <tr>
+ <td>GET</td>
+ <td>/session/{session id}</td>
+ <td><a>Get Session</a></td>
+ </tr>
+
+ <tr>
+ <td>POST</td>
+ <td>/session/async</td>
+ <td><a>Async New Session</a></td>
+ </tr>
+
+ <tr>
+ <td>GET</td>
+ <td>/session/async/{<var>session creation job id</var>}{/<var>event</var>}
+ <td><a>Async New Session Status</a></td>
+ </tr>
+
+ <tr>
+ <td>DELETE</td>
+ <td>/session/async/{<var>session creation job id</var>}
+ <td><a>Cancel New Session</a></td>
+ </tr>
+
<tr>
<td>DELETE</td>
<td>/session/{<var>session id</var>}</td>
@@ -1115,6 +1143,13 @@ <h3>Errors</h3>
both <a>editable</a> and <a>resettable</a>.
</tr>
+ <tr>
+ <td><dfn>invalid event id</dfn>
+ <td>400
+ <td><code>invalid event id</code>
+ <td>Argument was an invalid event ID.
+ </tr>
+
<tr>
<td><dfn>invalid selector</dfn>
<td>400
@@ -1122,6 +1157,15 @@ <h3>Errors</h3>
<td>Argument was an invalid selector.
</tr>
+ <tr>
+ <td><dfn>invalid session creation job id</dfn>
+ <td>404
+ <td><code>invalid session creation job id</code>
+ <td>Occurs if the given <a>session creation job id</a> is not in the list of <a>session creation jobs</a>,
+ or is in the list but has a <a data-lt="session creation status">status</a> of
+ "<code>cancelled</code>" or "<code>failed</code>".
+ </tr>
+
<tr>
<td><dfn>invalid session id</dfn>
<td>404
@@ -1130,6 +1174,13 @@ <h3>Errors</h3>
meaning the <a>session</a> either does not exist or that it’s not active.
</tr>
+ <tr>
+ <td><dfn>invalid timeout</dfn>
+ <td>400
+ <td><code>invalid timeout</code>
+ <td>Argument was an invalid timeout.
+ </tr>
+
<tr>
<td><dfn>javascript error</dfn>
<td>500
@@ -2054,8 +2105,242 @@ <h2>Sessions</h2>
an <a>intermediary node</a> will also <a>close the session</a> of
the <a>associated session</a>.
-<p>All <a>commands</a>, except <a>New Session</a> and <a>Status</a>,
- have an associated <dfn>current session</dfn>,
+<p>A <a>remote end</a> has an associated
+ <dfn>maximum timeout for async session creation</dfn> in milliseconds
+ (an Integer). It may be <a><code>null</code></a> if “unlimited”.
+
+ <p>A <a>remote end</a> has an associated
+ <dfn>wait time for async session creation</dfn> in milliseconds
+ (an Integer). It may be <a><code>null</code></a> if “unlimited”.
+
+<p>A <dfn>session creation job</dfn> is a task to create a session:</a>
+
+<table class=simple>
+<tr>
+<th>Field
+<th>Default
+<th>JSON key
+<th>Optional<sup>†</sup>
+<th>Nullable
+<th>Description<sup>†</sup>
+</tr>
+
+<tr>
+<td><dfn>Session creation job ID</dfn>
+<td>
+<td>"<code>sessionCreationJobId</code>"
+<td>
+<td>
+<td>A string representation of a <a>UUID</a> used to uniquely identify this job.
+</tr>
+
+<tr>
+<td><dfn>Session creation status</dfn>
+<td>"<code>queuing</code>"
+<td>"<code>status</code>"
+<td>
+<td>
+<td>String indicating session creation status,
+ one of "<code>queueing</code>", "<code>creating</code>", "<code>created</code>",
+ "<code>failed</code>", and "<code>cancelled</code>".
+</tr>
+
+<tr>
+<td><dfn>Capabilities request</dfn>
+<td>Empty JSON <a>Object</a>
+<td>"<code>capabilitiesRequest</code>"
+<td>
+<td>
+<td>The capabilities request.
+</tr>
+
+<tr>
+<td><dfn>Session creation timeout</dfn>
+<td>600,000
+<td>"<code>timeout</code>"
+<td>
+<td>✓
+<td>Specified as an <a>integer</a> in milliseconds.
+ If session creation is not achieved within this timeout,
+ the job should be failed.
+ If <a><code>null</code></a>,
+ there is no timeout beyond implementation limits.
+</tr>
+
+<tr>
+<td><dfn>Session creation requested time</dfn>
+<td>
+<td>"<code>requestedTime</code>"
+<td>
+<td>
+<td>When the session creation was requested as a <a>millisecond timestamp</a>.
+</tr>
+
+<tr>
+<td><dfn>Session creation ended time</dfn>
+<td>
+<td>"<code>endedTime</code>"
+<td>✓
+<td>
+<td>When the job ended in success or failure as a <a>millisecond timestamp</a>.
+</tr>
+
+<tr>
+<td><a>Session ID</a>
+<td>
+<td>"<code>sessionId</code>"
+<td>✓
+<td>
+<td><a>Session ID</a> of the created session.
+</tr>
+
+<tr>
+<td><dfn>Session creation events</dfn>
+<td>Empty JSON <a>List</a>
+<td>"<code>events</code>"
+<td>
+<td>
+<td>Time-ordered list of session creation events.
+</tr>
+
+<tr>
+<td><dfn>Session creation data</dfn>
+<td></a>
+<td>"<code>data</code>"
+<td>✓
+<td>
+<td>Object containing implementation-defined data associated with this job.
+</tr>
+</table>
+
+<!-- This should be a <figcaption>, but we can fix that later: -->
+<p style="text-align: right; font-size: 90%">
+<sup>†</sup> Informative.
+
+<div class="issue" title="Session creation timeouts">
+ <p>Should session creation jobs have multiple timeouts,
+ for example overall job timeout and wait timeout?
+</div>
+
+<div class="issue" title="Session creation attempts">
+<p>Should we require representation of session creation attempts?
+
+ <p>Compare <a href="https://docs.aws.amazon.com/en_pv/batch/latest/APIReference/API_DescribeJobs.html">AWS Batch Describe Jobs</a>.
+</div>
+
+<div class="issue" title="Time property names">
+<p>Should we use a common suffix like <code>Time</code> for names of properties representing times?
+
+<p>The <a href="http://appium.io/docs/en/advanced-concepts/event-timings/">Appium event timings API</a> uses the suffix <code>Time</code> but represents times using “JS timestamps”,
+ presumably milliseconds as provided by <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now"><code>Date.now</code></a>.
+
+<p>The <a href="https://docs.aws.amazon.com/en_pv/devicefarm/latest/APIReference/API_GetJob.html">AWS Device Farm Get Job endpoint</a> uses no suffix,
+ for example "<code>started</code>".
+
+<p>The <a href="https://wiki.saucelabs.com/display/DOCS/Tunnel+Methods#TunnelMethods-GetTunnel">SauceLabs Get Tunnel endpoint</a> uses no suffix,
+ for example "<code>last_connected</code>".
+
+<p>If we do use a suffix, should we specify the units,
+ for example <code>endedTimeMillis</code>?
+</div>
+
+<p>A <dfn>session creation event</dfn> is an event that occurred in the course of trying to create a session:
+
+<table class=simple>
+<tr>
+<th>Field
+<th>Default
+<th>JSON key
+<th>Optional
+<th>Nullable
+<th>Description
+</tr>
+
+<tr>
+<td><dfn>Event ID</dfn>
+<td>
+<td>"<code>eventId</code>"
+<td>
+<td>
+<td>A string representation of a <a>UUID</a> used to uniquely identify this event.
+</tr>
+
+<tr>
+<td><dfn>Event time</dfn>
+<td>
+<td>"<code>time</code>"
+<td>
+<td>
+<td>Event time as a <a>millisecond timestamp</a>.
+</tr>
+
+<tr>
+<td><dfn>Event type</dfn>
+<td>"<code>progress</code>"
+<td>"<code>type</code>"
+<td>✓
+<td>
+<td>Type of this event: "<code>progress</code>" or "<code>error</code>" <span class=issue>or a vendor-prefixed extension type</span>
+</tr>
+
+<tr>
+<td><dfn>Message</dfn>
+<td>
+<td>"<code>message</code>"
+<td>
+<td>
+<td>Human readable description of an event.
+</tr>
+
+<tr>
+<td><dfn>Event data</dfn>
+<td>
+<td>"<code>data</code>"
+<td>✓
+<td>
+<td>Object containing implementation-defined data associated with this event.
+</tr>
+
+<tr>
+<td><dfn>Event stack trace</dfn>
+<td>""
+<td>"<code>stacktrace</code>"
+<td>✓
+<td>
+<td>A stack trace report of the active stack frames at the time when the event occurred.
+</tr>
+</table>
+
+<div class=issue title="Events or logs?">
+ <p>Should session creation progress be represented using “events” or “logs”?
+</div>
+
+<p>A <a>remote end</a> will maintain a list of <dfn>session creation jobs</dfn>.
+
+<p>With an implementation-specific schedule and priority,
+ a remote end should work on session creation jobs with a
+ <a data-lt="session creation status">status</a> of "<code>queueing</code>".
+
+<div class="issue" title="Define session creation job processing">
+ Needs more definition than “work on”.
+</div>
+
+<p>For each <a>session creation job</a>, an <a>intermediary node</a> will
+ maintain a list of <dfn>associated session creation jobs</dfn>.
+ These include each <a>session creation job</a> on any <a>upstream</a> neighbor
+ that is created when the <a>intermediary node</a> executes the
+ <a>Async New Session</a> <a>command</a> to complete the job.
+
+<p>For each <a>session creation job</a>, an <a>intermediary node</a> will
+ maintain a associated list of sessions. These include
+ each <a>session</a> on any <a>upstream</a> neighbor that is created
+ when the <a>intermediary node</a> executes a <a>New
+ Session</a> <a>command</a> to complete the job.
+
+<a>New Session</a>, <a>Async New Session</a>, and <a>Status</a> <a>commands</a>
+ have no associated <a>session</a> or <a>session creation job</a>.
+
+<p>All other <a>commands</a> have an associated <dfn>current session</dfn>,
which is the <a>session</a> in which that <a>command</a> will run.
<p>A <a>remote end</a> has an associated list of
@@ -2361,6 +2646,255 @@ <h3 id=new-session><dfn data-lt="new sessions|creating a new session">New Sessio
</ol>
</section> <!-- /New Session -->
+<section>
+<h3><dfn>Get Session</dfn></h3>
+
+<table class="simple jsoncommand">
+ <tr>
+ <th>HTTP Method</th>
+ <th>URI Template</th>
+ </tr>
+ <tr>
+ <td>GET</td>
+ <td>/session/{session id}</td>
+ </tr>
+</table>
+
+<p>The <a>remote end steps</a> are:
+
+<ol>
+ <li><p>Let <var>body</var> be a JSON <a>Object</a> initialised with:
+ <dl>
+ <dl>
+ <dt>"<code>sessionId</code>"
+ <dd>The <a>session id</a> of the <a>current session</a>.
+
+ <dt>"<code>capabilities</code>"
+ <dd>The capabilities of the <a>current session</a>.
+
+ <dt>"<code>capabilitiesRequest</code>"
+ <dd>The capabilities request for the <a>current session</a>.
+ </dl>
+ </dl>
+
+ <li><p>Return success with data <var>body</var>.
+</section> <!-- /Get Session -->
+
+<section>
+<h3><dfn>Async New Session</dfn></h3>
+
+<table class="simple jsoncommand">
+ <tr>
+ <th>HTTP Method</th>
+ <th>URI Template</th>
+ </tr>
+ <tr>
+ <td>POST</td>
+ <td>/session/async</td>
+ </tr>
+</table>
+
+<p>The <a>remote end</a> steps are:
+
+<ol>
+ <li><p>Let <var>session creation requested time</var> be the current time
+ in milliseconds since the Epoch as an integer.
+
+ <li><p>Let <var>timeout</var> be the result of <a>getting the
+ property</a> named <var>timeout</var> from <var>parameters</var>.
+
+ <ol>
+ <li><p>If <a>maximum timeout for async session creation</a> is an <a>integer</a>,
+ and <var>timeout</var> is undefined,
+ let <var>timeout</var> be <a>min</a>(600,000, <a>maximum timeout for async session creation</a>).
+ <li><p>If <a>maximum timeout for async session creation</a> is <a><code>null</code></a>,
+ and <var>timeout</var> is undefined,
+ let <var>timeout</var> be 600,000</a>.
+ <li><p>If <var>timeout</var> is <a><code>null</code></a>,
+ let <var>timeout</var> be <a>maximum timeout for async session creation</a>.
+ <li><p>If <a>maximum timeout for async session creation</a> is an <a>integer</a>,
+ and less than <var>timeout</var>,
+ return <a>error</a> with <a>error code</a> <a>invalid timeout</a>.
+ <li><p>If <a>timeout</a> is not <a><code>null</code></a> or an <a>integer</a>,
+ return <a>error</a> with <a>error code</a> <a>invalid argument</a>.
+ </ol>
+
+ <li><p>If the <a>remote end</a> is an <a>intermediary node</a>, take
+ implementation-defined steps that either result in returning
+ an <a>error</a> with <a>error code</a> <a>session not created</a>,
+ or in returning a <a>success</a> with data that is isomorphic to
+ that returned by <a>remote ends</a> according to the rest of this
+ algorithm.
+
+ <li><p>If the <a>maximum active sessions</a> is equal to
+ the length of the list of <a>active sessions</a>,
+ return <a>error</a> with <a>error code</a> <a>session not created</a>.
+
+ <li><p>Let <var>capabilities</var> be the result
+ of <a>trying</a> to <a>process capabilities</a>
+ with <var>parameters</var> as an argument.
+
+ <li><p>If <var>capabilities</var> is <a><code>null</code></a>,
+ return <a>error</a> with <a>error code</a> <a>session not created</a>.
+
+ <li><p>Let <var>session creation job</var> be a new JSON <a>Object</a>
+ with the following properties:
+
+ <dl>
+ <dt>"<code>sessionCreationJobId</code>"
+ <dd>The result of <a>generating a UUID</a>.
+
+ <dt>"<code>status</code>"
+ <dd>The String constant "<code>queuing</code>".
+
+ <dt>"<code>capabilitiesRequest</code>"
+ <dd>The result of <a>getting the property</a> named <var>capabilities</var> from <var>parameters</var>.
+
+ <dt>"<code>timeout</code>"
+ <dd><var>timeout</var>’s value.
+
+ <dt>"<code>requestedTime</code>"
+ <dd><var>session creation requested time</var>’s value.
+
+ <dt>"<code>events</code>"
+ <dd>An empty JSON <a>List</a>.
+
+ <dt>"<code>data</code>"
+ <dd>A JSON <a>Object</a> with implementation-specific data.
+ </dl>
+
+ <li>Add the <var>session creation job</var> to the list of
+ <a>session creation jobs</a>.
+</ol>
+
+</section> <!-- /Async New Session -->
+
+<section>
+<h3><dfn>Async New Session Status</dfn></h3>
+
+<table class="simple jsoncommand">
+ <tr>
+ <th>HTTP Method</th>
+ <th>URI Template</th>
+ </tr>
+ <tr>
+ <td>GET</td>
+ <td>/session/async/{<var>session creation job id</var>}{/<var>event</var>}</td>
+ </tr>
+</table>
+
+<p>The <a>remote end steps</a> are:
+
+<ol>
+ <ol>
+ <li><p>Let <var>session creation job</var> be the job in <a>session creation jobs</a>
+ with a <a>session creation job id</a> matching <var>session creation job id</var>.
+
+ <li><p>If <var>session creation job</var> is <a><code>null</code></a>,
+ return <a>error</a> with <a>error code</a> <a>invalid session creation job id</a>.
+
+ <li><p>Let <var>body</var> be a <a>JSON clone</a> of <var>session creation job</var>.
+
+ <li><p>If <var>event</var> is defined:
+
+ <ol>
+ <li><p>Let <var>filtered events</var> be an empty JSON <a>List</a>.
+
+ <li><p>Let <var>found</var> be false.
+
+ <li><p>Let <var>events</var> be the value of <a>getting a property</a> named <var>events</var> from <var>body</var>.
+
+ <li><p>For each <var>event object</var> in <var>events</var> in reverse order:
+
+ <ol>
+ <li><p>If <var>found</var> is true, then break.
+
+ <li><p>Let <var>event id</var> be the value of <a>getting a property</a> named <var>eventId</var> from <var>event object</var>.
+
+ <li><p>If <var>event</var> equals <var>event id</var>,
+ set <var>found</var> to true.
+
+ <li><p>Prepend <var>event object</var> to <var>filtered events</var>.
+ </ol>
+
+ <li><p>If <var>found</var> is false,
+ return <a>error</a> with <a>error code</a> <a>invalid event id</a>.
+
+ <li>Set property <var>events</var> in <var>body</var> to <var>filtered events</var>.
+ </ol>
+
+ <li><p>Let <var>status</var> be the value of <a>getting a property</a> named <var>status</var> from <var>body</var>.
+
+ <li><p>Let <var>cache timeout</var> be <a><code>null</code></a>.
+
+ <li><p>If <var>status</var> is "<code>queueing</code>" or "<code>creating</code>",
+ then set <var>cache timeout</var> to 1,000
+ or an implementation-defined predicted interval to the next event.
+
+ <li><p><a>Set a property</a> on <var>body</var> with name <var>cacheTimeout</code> and value <var>cache timeout</var>.
+
+ <p class=note>Local ends may use the <var>cacheTimeout</var> property to hint when to next poll for status.
+
+ <li><p>Return success with data <var>body</var>.
+</ol>
+</section> <!-- /Async New Session Status -->
+
+<section>
+<h3><dfn>Cancel New Session</dfn></h3>
+
+<table class="simple jsoncommand">
+ <tr>
+ <th>HTTP Method</th>
+ <th>URI Template</th>
+ </tr>
+ <tr>
+ <td>DELETE</td>
+ <td>/session/async/{<var>session creation job id</var>}</td>
+ </tr>
+</table>
+
+<p>The <a>remote end steps</a> are:
+
+<ol>
+ <li><p>Let <var>session creation job</var> be the job in <a>session creation jobs</a>
+ with a <a>session creation job id</a> matching <var>session creation job id</var>.
+
+ <li><p>If <var>session creation job</var> is <a><code>null</code></a>,
+ return <a>error</a> with <a>error code</a> <a>invalid session creation job id</a>.
+
+ <li><p>If <var>session creation job</var> has a <a data-lt="session creation status">status</a> of
+ "<code>cancelled</code>" or "<code>failed</code>",
+ return <a>error</a> with <a>error code</a> <a>invalid session creation job id</a>.
+
+ <li><p>If <var>session creation job</var> has a <a data-lt="session creation status">status</a> of
+ "<code>created</code>":
+
+ <ol>
+ <li>Set the <a data-lt="session creation status">status</a> to "<code>cancelled</code>".
+
+ <li>If <var>session creation job</var>’s job <a>session ID</a> references an <a>active session</a>,
+ schedule a background job to <a>try</a> to <a>close the session</a>.
+ </ol>
+
+ <li><p>If <var>session creation job</var> has a <a data-lt="session creation status">status</a> of
+ "<code>queuing</code>" or "<code>creating</code>"
+ and its <a>session ID</a> references an <a>active session</a>:
+
+ <ol>
+ <li>Set <var>session creation job</var>’s <a data-lt="session creation status">status</a> to "<code>cancelled</code>".
+ <li>Set <var>session creation job</var>’s <a data-lt="session creation ended time">ended time</a> to the current <a>millisecond timestamp</a>.
+ <li>Schedule a background job to cancel the session creation.
+ </ol>
+
+ <li><p>Return success with data <a><code>null</code></a>.
+</ol>
+
+<div class="issue" title="Cancel session creation">
+ <p>Define how to cancel session creation.</p>
+</div>
+
+</section> <!-- /Cancel New Session -->
+
<section>
<h3><dfn>Delete Session</dfn></h3>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment