You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If I do await { then: fn }, then code running in fn will always see an async ID of 1 until after an Immediate (or "lower priority" tick) is made, then it will start seeing 0 instead. I expect it instead to be the same async ID as the resource in which the call was made... see the below repro for expectations vs. actual results.
The culprit here is probably the same as in #22360, but discussion there has stalled. Also, I think the example here is easier to comprehend.
Repro
constasyncHooks=require('async_hooks');// activate async_hooksasyncHooks.createHook({init: ()=>{}}).enable();// a custom thenableconstthenable=()=>({then: (fn)=>{console.log(asyncHooks.executionAsyncId());fn();}});asyncfunctionmain(){// On first tickconsole.log(asyncHooks.executionAsyncId());// prints 1awaitthenable();// prints 1 (expected)// After first thenableconsole.log(asyncHooks.executionAsyncId());// prints incremented IDawaitthenable();// still prints 1 (unexpected)// After high-priority tickawaitnewPromise(res=>process.nextTick(res));// tick nextTick queueconsole.log(asyncHooks.executionAsyncId());// prints incremented IDawaitthenable();// still prints 1 (unexpected)// After ImmediateawaitnewPromise(res=>setImmediate(res));// tick immediateconsole.log(asyncHooks.executionAsyncId());// prints incremented IDawaitthenable();// prints 0 (unexpected)// A workaroundconsole.log(asyncHooks.executionAsyncId());// prints incremented IDawaitthenable().then(_=>_);// prints same as above (expected)}main().catch(console.error);
Real-world use case example
The knex module seems to sometimes make DB queries in a Promise.prototype.then wrapper. If the Promise implementation happens to be userland, like in bluebird, then async context will be unknown at the DB query call site.
The text was updated successfully, but these errors were encountered:
if you want to track bluebird promises, bluebird needs to be async_hooks aware, or you need to patch async_hooks behaviour into it. async_hooks can't track what it doesn't know.
@devsnek I'm aware that bluebird doesn't currently have async_hooks interop, I believe it's an orthogonal issue. The bug here isn't whether the correct async ID is present in code running in the then callback, it's whether the correct async ID is present in the implementation of then itself.
kjin
changed the title
Awaited thenables have no async context after first tick
async_hooks: Awaited thenables have no async context after first tick
May 6, 2019
If I do
await { then: fn }
, then code running infn
will always see an async ID of1
until after an Immediate (or "lower priority" tick) is made, then it will start seeing0
instead. I expect it instead to be the same async ID as the resource in which the call was made... see the below repro for expectations vs. actual results.The culprit here is probably the same as in #22360, but discussion there has stalled. Also, I think the example here is easier to comprehend.
Repro
Real-world use case example
The
knex
module seems to sometimes make DB queries in aPromise.prototype.then
wrapper. If thePromise
implementation happens to be userland, like inbluebird
, then async context will be unknown at the DB query call site.The text was updated successfully, but these errors were encountered: