async_hooks: no way to EmitDestroy on garbage collection with the high-level Embedder API

  • Version: 8.7
  • Platform:
  • Subsystem: async_hooks

Let's say I make a super simple AsyncResource, that lets me bind a function to always run in a particular executionId.

class BoundFunction extends asyncHooks.AsyncResource {

  constructor(f, bindTimeAsyncId) {
    super('CONTEXT_BIND', bindTimeAsyncId);
    this.f = f;
  }

  run() {
    this.emitBefore();
    const ret = this.f();
    this.emitAfter();
    return ret;
  }
}

I can use it with the following wrapper:

function bind(f) {

  const bindTimeAsyncId = asyncHooks.executionAsyncId();
  const boundF = new BoundHook(f, bindTimeAsyncId);

  return () => boundF.run();
}

However, it seems I have no way to schedule cleanup. Let's say I do

const f = () => console.log(`hello from ${asyncHooks.executionAsyncId()}`);
const boundF = bind(f);

I want BoundFunction#emitDestroy() to run once the GC grabs boundF. The docs seem to say that this is a normal approach to async resources, by

Note: Some resources depend on garbage collection for cleanup, so if a reference is made to the resource object passed to init it is possible that destroy will never be called, causing a memory leak in the application. If the resource does not depend on garbage collection, then this will not be an issue.

However, as far as I can see the JS Embedder API gives me no way to achieve this behaviour.