Skip to content

Make async/await monkey-patchable #142

Closed
@bmeurer

Description

@bmeurer

I'd like to bring up an idea from @gsathya here, which could help to make progress short-/middle-term while we're resolving the performance problems with async_hooks, specifically with promise hooks. As mentioned in nodejs/benchmarking#181 (comment) just enabling async_hooks on a simple hapi v17 server already causes a 30% performance drop, which is way below what's acceptable.

Results for Node 9.4.0

Given the discussions I've had with some many people from the Node community about this since NodeConfEU, I see several ways to make progress on this, but no easy path forward. We might need to make some difficult decisions in what hooks we want to support for promises and the trade-offs for performance we're willing to make. Unfortunately, as pointed out by @ofrobots and others, we're kind of in a hurry now, since async/await is a thing already and monkey-patching doesn't work there because of the way the specification is written. So essentially vendors are forced to use async_hooks now for their monitoring tools, even though it's not ready, and might even undergo breaking changes while it's in EXPERIMENTAL.

So in order to buy us some time, and maybe even enable things like zone.js in the browser, we could instead change the specification to essentially make await monkey-patchable. That means we need to change the places in the specification that allocate the implicit promises for async and await,

image

and also make await lookup "then" on the promise instead of hardcoding the internal operation.

image

Both of which sounds somewhat straight-forward, and V8 can still optimize the common case (no prototype mutation) as it does today, i.e. skip the "then" lookup on native promises if we know that no one touched Promise.prototype.then. I think this change could even be back-ported to Node 8. I also think that making such a change wouldn't break web compatibility, although it makes await monkey-patchable in some sense. It would probably still take a while to change the spec, but Node/V8 wouldn't need to wait for that to reach stage 4.

What do you folks think?

cc @nodejs/collaborators @jasnell @ofrobots @littledan @gsathya @caitp @hashseed @AndreasMadsen @mathiasbynens

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions