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

Reject promises for in-progress operations on an MLTensor if it is destroyed #799

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
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
23 changes: 20 additions & 3 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,10 +1080,16 @@ Reads back the {{MLTensor/[[data]]}} of an {{MLTensor}} from the {{MLContext}}.{
1. If |tensor|.{{MLTensor/[[isDestroyed]]}} is true, then return [=a new promise=] [=rejected=] with a {{TypeError}}.
1. If |tensor|.{{MLTensor/[[descriptor]]}}.{{MLTensorDescriptor/readable}} is false, then return [=a new promise=] [=rejected=] with a {{TypeError}}.
1. Let |promise| be [=a new promise=].
1. [=set/Append=] |promise| to |tensor|.{{MLTensor/[[pendingPromises]]}}.
1. Enqueue the following steps to |tensor|.{{MLGraph/[[context]]}}.{{MLContext/[[timeline]]}}:
1. Let |bytes| be a [=/byte sequence=] containing a copy of |tensor|.{{MLTensor/[[data]]}}.
1. If that fails, then [=queue an ML task=] with |global| to [=reject=] |promise| with an "{{UnknownError}}" {{DOMException}}, and abort these steps.
1. Otherwise, [=queue an ML task=] with |global| to [=ArrayBuffer/create=] an {{ArrayBuffer}} |result| given |bytes| and |realm| and then [=resolve=] |promise| with |result|.
1. If that fails, then [=queue an ML task=] with |global| and the following steps:
1. [=set/Remove=] |promise| from |tensor|.{{MLTensor/[[pendingPromises]]}}.
1. [=Reject=] |promise| with an "{{UnknownError}}" {{DOMException}}.
1. Otherwise, [=queue an ML task=] with |global| and the following steps:
1. [=set/Remove=] |promise| from |tensor|.{{MLTensor/[[pendingPromises]]}}.
1. Let |buffer| be the result of [=ArrayBuffer/creating=] an {{ArrayBuffer}} from |bytes| in |realm|.
1. [=Resolve=] |promise| with |buffer|.
1. Return |promise|.
</details>

Expand All @@ -1109,10 +1115,14 @@ Bring-your-own-buffer variant of {{MLContext/readTensor(tensor)}}. Reads back th
1. If |tensor|.{{MLTensor/[[descriptor]]}}.{{MLTensorDescriptor/readable}} is false, then return [=a new promise=] [=rejected=] with a {{TypeError}}.
1. If [=validating buffer with descriptor=] given |outputData| and |tensor|.{{MLTensor/[[descriptor]]}} returns false, then return [=a new promise=] [=rejected=] with a {{TypeError}}.
1. Let |promise| be [=a new promise=].
1. [=set/Append=] |promise| to |tensor|.{{MLTensor/[[pendingPromises]]}}.
1. Enqueue the following steps to |tensor|.{{MLGraph/[[context]]}}.{{MLContext/[[timeline]]}}:
1. Let |bytes| be a [=/byte sequence=] containing a copy of |tensor|.{{MLTensor/[[data]]}}.
1. If that fails, then [=queue an ML task=] with |global| to [=reject=] |promise| with an "{{UnknownError}}" {{DOMException}}, and abort these steps.
1. If that fails, then [=queue an ML task=] with |global| and the following steps:
1. [=set/Remove=] |promise| from |tensor|.{{MLTensor/[[pendingPromises]]}}.
1. [=Reject=] |promise| with an "{{UnknownError}}" {{DOMException}}.
1. Otherwise, [=queue an ML task=] with |global| and the following steps:
1. [=set/Remove=] |promise| from |tensor|.{{MLTensor/[[pendingPromises]]}}.
1. If |outputData| is [=BufferSource/detached=], [=reject=] |promise| with a {{TypeError}}, and abort these steps.

Note: [=Validating buffer with descriptor=] above will fail if |outputData| is detached, but it is possible that |outputData| could be detached between that step and this one.
Expand Down Expand Up @@ -1478,6 +1488,10 @@ interface MLTensor {
::
The {{MLTensor}}'s descriptor.

: <dfn>\[[pendingPromises]]</dfn> of type [=/set=] of {{Promise}}s
::
Promises corresponding to {{MLContext}}.{{MLContext/readTensor(tensor)}} method calls which are in-progress and have yet to resolve. All pending promises will be rejected when the {{MLTensor}} is destroyed.

: <dfn>\[[isDestroyed]]</dfn> of type {{boolean}}
::
Whether {{MLTensor}}.{{MLTensor/destroy()}} has been called. Once destroyed, the {{MLTensor}} can no longer be used.
Expand Down Expand Up @@ -1528,6 +1542,9 @@ Releases the resources associated with the {{MLTensor}}. This method is idempote
The <dfn method for=MLTensor>destroy()</dfn> method steps are:
</summary>
1. Set [=this=].{{MLTensor/[[isDestroyed]]}} to true.
1. [=set/For each=] |promise| in [=this=].{{MLTensor/[[pendingPromises]]}}:
1. [=set/Remove=] |promise| from [=this=].{{MLTensor/[[pendingPromises]]}}.
1. [=Reject=] |promise| with an "{{InvalidStateError}}" {{DOMException}}.
1. Enqueue the following steps to [=this=].{{MLTensor/[[context]]}}.{{MLContext/[[timeline]]}}:
1. Release [=this=].{{MLTensor/[[data]]}}.
1. Return {{undefined}}.
Expand Down
Loading