From 73ba57c2c42073e9b092b33ae9e1d16b26f3ffb5 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Thu, 29 Jun 2023 23:02:09 -0400 Subject: [PATCH] better/safer EV set/withValue - must be used with >=5.0.2-5 of fibers --- packages/meteor/dynamics_nodejs.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/meteor/dynamics_nodejs.js b/packages/meteor/dynamics_nodejs.js index d98a608dfc53..ca6221a678bd 100644 --- a/packages/meteor/dynamics_nodejs.js +++ b/packages/meteor/dynamics_nodejs.js @@ -21,10 +21,18 @@ Meteor._nodeCodeMustBeInFiber = function () { Object.defineProperty(Fiber.prototype, '_meteor_dynamics', { get() { - return __async_meteor_dynamics.getStore() || []; + return __async_meteor_dynamics.getStore(); + }, + set(store) { + // opinionated - but there are no situations I can think of where we want to set the root _meteor_dynamics. + if (executionAsyncId() === 0) { + throw new Error('Trying to call Fiber.current._meteor_dynamics = [...] at the global execution ID'); + } + __async_meteor_dynamics.enterWith(store); } }); + /** * @memberOf Meteor * @summary Constructor for EnvironmentVariable @@ -76,18 +84,12 @@ EVp.getOrNullIfOutsideFiber = function () { EVp.withValue = function (value, func) { const current = (__async_meteor_dynamics.getStore() || []).slice(); current[this.slot] = value; - if (!Fiber.current) { - // this is necessary as if we aren't in a fiber, the current async scope may be poluted - // particularly bad if this is the root async scope - which it often is inside a fiber - // in the future we may loosen this restriction to only require there be a current fiber if - // the current executionAsyncId == 0 (e.g., the root) - this will allow us to call withValue - // after an await without poluting the root AsyncResource. However, this may not resolve the concerns - // of poluting some other shared async resource. + if (!Fiber.current && executionAsyncId() === 0) { // running the full meteor test suite (in particular, mongo and ddp*) multiple times in a single build // should expose any flaws with changes made here. throw new Error('You can\'t call withValue from outside a Fiber. Perhaps you awaited something before calling this?'); } - return Fiber.current.runInAsyncScope(() => __async_meteor_dynamics.run(current, func)); + return __async_meteor_dynamics.run(current, func); }; /**