Skip to content
🗿 Archive

Moving from domains to async_hooks: plans for addressing common resource pools #16098

🗿 Archive
3y ago
· 8 replies
  • Version: All
  • Platform: All
  • Subsystem: domain

Hi all 👋

The meta-problem: Many core contributors have expressed a desire to get rid of domains. In order to get rid of domains, it's also been expressed that Node should provide migration routes for users. Domains provide two functions to users: the ability to intercept uncaught exceptions for a subset of all JS execution, and (as a useful side-effect of the first function) the ability to associate multiple asynchronous continuations with a single JS object (available contextually per continuation at process.domain). It's this second function of domains that brings me to this issue!

Since async hooks are now an official (if experimental) API, I took some time to explore moving pg-db-session from domains to async hooks. pg-db-session uses the second function of domains — the ability to associate multiple continuations with a well-known object — to back continuation local storage. Specifically, we use this to associate all continuations associated with a particular HTTP request to a postgres session. (An aside: this has been in production & has worked swimmingly for the last year and a half, with no memory leaks. At the time the library was written, AsyncHooks weren't quite sufficient for our needs.)

The problem: In moving from domains to async hooks, I ran into the resource pooling problem. This is the problem where, given pool X, and requests A and B:

  • request A takes out a resource from pool X.
  • request A does work with the resource. This succeeds, the resource is associated with request A.
  • request A returns the resource to pool X.
  • request B takes out a resource from pool X.
  • request B does work with the resource. This fails, the resource is still associated with request A.

Domains solved this problem (mostly) through community outreach: many popular pooling libraries now include some variant of cb = process.domain ? process.domain.bind(cb) : cb. Internally, for all of the pools Node implements async-hooks appears to be well-behaved (e.g., http agents & timers — incidentally, 🎉 great work! 🎉) Externally, we appear to have an embedder API.

My questions are:

  • Do we have an AsyncResource guide for handle pool implementors?
  • Is there a coordinated effort to reach out to popular handle pool libraries (generic-pool, pg-pool, redis, et al) to add AsyncResource support?
  • What is the CTC's plan for removing domain support? Is there a list of packages we need to upgrade before dropping support?

Replies

@Trott Trott
Maintainer

What is the CTC's plan for removing domain support? Is there a list of packages we need to upgrade before dropping support?

@chrisdickinson I speak as only one member of the TSC (there is no CTC anymore) and not on behalf of the entire committee. That said: As far as I can tell, there is no plan for removing domain support. I suspect there is a minority of TSC members who see only downside (ecosystem breakage) to removing domains at any point in the foreseeable future.

Yes, there are people who would like to work actively towards its removal. I personally don't see it happening any time soon, and possibly ever.

Caveat/disclaimer: I'm not expressing my opinion on domain deprecation and removal here. This is my sense of where things stand with the committee as a whole. Perhaps there are others with a significantly different sense of where things stand with the committee. Perhaps those people have a more accurate assessment than mine.

@refack refack
Collaborator

Refs: hapi dropping domains support - #16093

Great example of what is one of the major challenges we have IMHO - getting representative information of ecosystems usages and opinions...

Removing domain, except for API cohesiveness, has performance, extendability and maintainability benefits. So it's not net breakage.


@chrisdickinson as per your quastions:

  • Do we have an AsyncResource guide for handle pool implementors?

As "usual" documentation is not core's biggest forte. We have async_hooks.html#async_hooks_javascript_embedder_api. Any contribution will be highly appreciated.

  • Is there a coordinated effort to reach out to popular handle pool libraries (generic-pool, pg-pool, redis, et al) to add AsyncResource support?

Not AFAIK.

/cc @nodejs/community-committee @nodejs/async_hooks

@jasnell jasnell
Maintainer

Do we have an AsyncResource guide for handle pool implementors?

Not yet, but there are discussions happening around this. The key blocker for making progress is in getting enough implementation experience to actually have best practices to put into such a guide.

Is there a coordinated effort to reach out to popular handle pool libraries (generic-pool, pg-pool, redis, et al) to add AsyncResource support?

Coordinated? No, not yet, but this raises an important point that goes hand in hand with your question above. I believe @trevnorris and @AndreasMadsen each have explored this to various extents, as have others, but those have been far from coordinated.

FWIW, there are a couple of folks who mentioned to me at Interactive last week that they were independently looking in to re-implementing domains on top of async hooks and at least one who had a functional prototype.

What is the CTC's plan for removing domain support? Is there a list of packages we need to upgrade before dropping support?

At this point, the answer to the first question is: There is no plan yet. The domains API is still used by far too many modules for us to consider removing it or even putting a runtime deprecation in. Help coming up with the list of packages to upgrade would be appreciated.

3y

@AndreasMadsen AndreasMadsen
Collaborator

Do we have an AsyncResource guide for handle pool implementors?

Not yet, but there are discussions happening around this. The key blocker for making progress is in getting enough implementation experience to actually have best practices to put into such a guide.

Well, I don't know. How much experience is needed? Given a concrete example, the solutions are often quite clear to me, although I completely understand why they are not clear to everyone. There are some cases where the strategy is not as clear: #14238

Is there a coordinated effort to reach out to popular handle pool libraries (generic-pool, pg-pool, redis, et al) to add AsyncResource support?

Coordinated? No, not yet, but this raises an important point that goes hand in hand with your question above. I believe @trevnorris and @AndreasMadsen each have explored this to various extents, as have others, but those have been far from coordinated.

I was hoping that APM providers would do this for us :) They have a huge incentive to do this and they already know the modules that causes issues.

FWIW, there are a couple of folks who mentioned to me at Interactive last week that they were independently looking into re-implementing domains on top of async hooks and at least one who had a functional prototype.

Yes, I don't see any reason why domain can't be implemented in core on top of async_hooks. There is likely some extra APIs that we will need, to do it outside core. Such as how it hooks into uncaughtException.

In any case, I think this is a necessary first step before we can evaluate if and when we want to remove domain.

@jkrems jkrems
Collaborator

Are other userland queueing packages affected by the same issue that bluebird is running into (no way to destroy since the lifetime is determined by GC)?

@Trott Trott
Maintainer

I don't think we're removing domains any time in the foreseeable future. I move that we close this issue. Or is there a different unanswered question at this time?

@misterdjules misterdjules
Collaborator

@Trott Is this issue about removing domains? I thought it was about issues that users can run into when using domains with pooled resources. If that's correct, then isn't this issue still relevant?

I'll edit the title to more clearly reflect the questions in the issue, which (I think) are still relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
7 participants
Converted from issue
Beta
You can’t perform that action at this time.