tc39 / proposal-explicit-resource-management

ECMAScript Explicit Resource Management

Home Page:https://arai-a.github.io/ecma262-compare/?pr=3000

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Should `Symbol.disposable` implementations generally be idempotant?

lucacasonato opened this issue · comments

We're currently determining what resources to implement Symbol.disposable for in Deno. It has come up as a question whether the Symbol.disposable / Symbol.asyncDisposable implementations for resources like subprocesses should be idempotant or not. As far as I can tell, the readme and spec does not give guidance on this right now, but looking at the examples and Web Platform resources, I think it should probably be.

An example:

{
  await using process = new Deno.Command("echo", { args: ["hello"] }).spawn();

  const output = await process.output(); // wait for the process to die, and collect the output

  // here `process` goes out of scope, and `await process[Symbol.asyncDispose]()` is called.
}

In this example, process is an object with a [Symbol.asyncDispose] method that internally calls kill(pid) and then waits for the process to shut down (await process.status). This does mean that if the process is already shut down (either because the user killed the process earlier, or because the process naturally died), kill(pid) will error because the process has already been reaped. Alternatively, we could catch this error when calling kill(pid).

What is the champions' guidance here? It would be great if we could record this guidance in the README and/or as a note in the spec.

The best practice is that calling [Symbol.dispose]() or [Symbol.asyncDispose]() twice on the same object should not throw, though if the object transitions from a disposed state back into a live state (such as reopening a closed connection, etc.) it could potentially throw upon a subsequent dispose.

This is already indicated within the specification text in the following two locations:

Great, thank you! I missed that. I'll close this then :)