Skip to content
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

Extended return type of invokeAction() #561

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 67 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,71 @@ <h2>The <dfn>InteractionOutput</dfn> interface</h2>
</ol>
</section>
</section>
<section> <h3>Using {{InteractionInput}} and {{InteractionOutput}}</h3>

<section data-dfn-for="ActionInteractionOutput">
<h2>The <dfn>ActionInteractionOutput</dfn> interface</h2>
<p>
Belongs to the <a>WoT Consumer</a> conformance class.
An {{ActionInteractionOutput}} object is always created by the implementations
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved
and exposes the data returned from <a>WoT Interactions</a> to application
scripts.
</p>
<p>
This interface exposes an action status object. Its implementation
will allow cancelling asynchronous actions and report the status of a long running action.
</p>
<pre class="idl">
enum ActionStatus {
/* "pending", Profile has pending. Not sure what it would mean? */
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved
"running",
"success", /* Profile uses completed? */
"error" /* Profile uses failed? */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we coordinate in some way with the Profile TF to align the terms that are being used? Or is it no problem if they differ, since they are operating on a different level anyway?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Once we feel comfortable with our choices we should definitely reach out. Most of the status terms are 1:1 matches. What seems different is pending.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: Profile has 4 terms

  • pending --> we don't have a corresponding term!
  • running -> same ✅
  • completed -> we use success instead
  • failed -> we use error instead

What can we do with aligning the terms? Use the ones from profile or talk to them? Any opinion?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, their terminology actually sounds quite good to me, so from my side we could also adopt what they are using.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine withe the Profile terms also. The question remains if it is fine dropping "pending" then... (same same but different 🙃)
Other opinions?

};

[SecureContext, Exposed=(Window,Worker)]
interface ActionInteractionOutput : InteractionOutput {
readonly attribute object? error;
Promise&lt;ActionStatus&gt; status();
Promise&lt;undefined&gt; cancel();
};
</pre>
<p>
The <dfn>error</dfn> property represents a possible error, initially `null`.
</p>
<p class="ednote" title="Should state be a function or an attribute only?">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started with a function but I start thinking an attribute should be sufficient..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An action is supposed to be always polled? Or could a script subscribe just for changes in status?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think observing state changes would be nice but I am not sure whether that is actually necessary...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, I tend to think now that a a function for reporting the status would be more powerful and useful. What do people think? Other ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, I tend to think now that a a function for reporting the status would be more powerful and useful. What do people think? Other ideas?

Hmm, if I see it correctly, we could also treat the attribute as a getter and add more logic to that if needed, right?

Or could a script subscribe just for changes in status?

If we wanted to that, what would be the best way to model that? Adding a way for registering a callback function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, maybe we should decide what we need/want from the status

  • is it likely that requesting the status may take a while? (or put differently do we need a Promise)
  • do we need a way to observe a status change (would be nice but adds complexity)

My take is that having a promise function for status() is fine while I am not 100% sure we should allow for listening status changes...

Are there opinions/proposals?


</p>
<p class="ednote" title="Additional action object functions needed?">
Should we allow pause/resume also? TD has no notion of it.
</p>
<section><h3>The <dfn>status()</dfn> function</h3>
Reports the status of an <a>Action</a> (one of <code>running</code>, <code>success</code> or <code>error</code>) or rejects on error. The method MUST run the following steps:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Reports the status of an <a>Action</a> (one of <code>running</code>, <code>success</code> or <code>error</code>) or rejects on error. The method MUST run the following steps:
Reports the status of an <a>Action</a> (one of <code>running</code>, <code>success</code>, or <code>error</code>), or rejects on error. The method MUST run the following steps:

<ol>
<li>
Return a {{Promise}} |promise:Promise| and execute the next steps
[=in parallel=].
</li>
<li>
TODO
</li>
</ol>
</section>
<section><h3>The <dfn>cancel()</dfn> function</h3>
Cancels a running WoT <a>Action</a> or rejects on error. The method MUST run the following steps:
<ol>
<li>
Return a {{Promise}} |promise:Promise| and execute the next steps
[=in parallel=].
</li>
<li>
TODO
</li>
</ol>
</section>

</section>

<section> <h3>Using {{InteractionInput}}, {{InteractionOutput}} and {{ActionInteractionOutput}}</h3>
<p>
As illustrated in the next pictures, the {{InteractionOutput}} interface
is used every time implementations provide data to scripts, while
Expand Down Expand Up @@ -1323,7 +1387,7 @@ <h2>The <dfn>InteractionOutput</dfn> interface</h2>
<p>
When a {{ConsumedThing}} invokes an <a>Action</a>, it provides the
parameters as {{InteractionInput}} and receives the output of the
<a>Action</a> as an {{InteractionOutput}} object.
<a>Action</a> as an {{ActionInteractionOutput}} object.
</p>
<p>
An {{ExposedThing}} <a href="#the-actionhandler-callback">
Expand Down Expand Up @@ -1386,7 +1450,7 @@ <h2>The <dfn>ConsumedThing</dfn> interface</h2>
/*Promise&lt;undefined&gt; writeAllProperties(
PropertyWriteMap valueMap,
optional InteractionOptions options = {});*/
Promise&lt;InteractionOutput&gt; invokeAction(DOMString actionName,
Promise&lt;ActionInteractionOutput&gt; invokeAction(DOMString actionName,
optional InteractionInput params = {},
optional InteractionOptions options = {});
Promise&lt;Subscription&gt; observeProperty(DOMString name,
Expand Down
12 changes: 10 additions & 2 deletions typescript/scripting-api/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ declare namespace WoT {
value(): Promise<DataSchemaValue>;
}

export enum ActionStatus { "running", "success", "error" }

export interface ActionInteractionOutput extends InteractionOutput {
error?: Error;
status(): Promise<ActionStatus>
cancel(): Promise<void>
}

export interface Subscription {
active:boolean,
stop(options?: InteractionOptions):Promise<void>
Expand Down Expand Up @@ -140,9 +148,9 @@ declare namespace WoT {
* Makes a request for invoking an Action and return the result.
* Takes as arguments actionName, optionally params and optionally options.
* It returns a Promise that resolves with the result of the Action represented
* as an InteractionOutput object, or rejects with an error.
* as an ActionInteractionOutput object, or rejects with an error.
*/
invokeAction(actionName: string, params?: InteractionInput, options?: InteractionOptions): Promise<undefined | InteractionOutput>;
invokeAction(actionName: string, params?: InteractionInput, options?: InteractionOptions): Promise<undefined | ActionInteractionOutput>;

/**
* Makes a request for Property value change notifications.
Expand Down