diff --git a/packages/callback-hook/hook.js b/packages/callback-hook/hook.js index 8710c09161..10330a3eb3 100644 --- a/packages/callback-hook/hook.js +++ b/packages/callback-hook/hook.js @@ -101,12 +101,6 @@ export class Hook { * @param iterator */ forEach(iterator) { - // Invoking bindEnvironment'd callbacks outside of a Fiber in Node doesn't - // run them to completion (and exceptions thrown from onException are not - // propagated), so we need to be in a Fiber. - if (Meteor._isFibersEnabled) { - Meteor._nodeCodeMustBeInFiber(); - } const ids = Object.keys(this.callbacks); for (let i = 0; i < ids.length; ++i) { diff --git a/packages/constraint-solver/constraint-solver.js b/packages/constraint-solver/constraint-solver.js index 6eccce483b..9337e65f5b 100644 --- a/packages/constraint-solver/constraint-solver.js +++ b/packages/constraint-solver/constraint-solver.js @@ -13,6 +13,7 @@ CS.PackagesResolver = function (catalog, options) { self._options = { nudge: options && options.nudge, + yield: options && options.yield, Profile: options && options.Profile, // For resultCache, pass in an empty object `{}`, and PackagesResolver // will put data on it. Pass in the same object again to allow reusing @@ -110,6 +111,7 @@ CS.PackagesResolver.prototype.resolve = async function (dependencies, constraint var resolveOptions = { nudge: self._options.nudge, + yield: self._options.yield, Profile: self._options.Profile }; @@ -170,6 +172,7 @@ CS.PackagesResolver._resolveWithInput = async function (input, options) { var solver = await (options.Profile || CS.DummyProfile).time("new CS.Solver", async function () { const _solver = new CS.Solver(input, { nudge: options.nudge, + yield: options.yield, Profile: options.Profile }); await _solver.init(); diff --git a/packages/constraint-solver/solver.js b/packages/constraint-solver/solver.js index f43398a1c4..102e957d43 100644 --- a/packages/constraint-solver/solver.js +++ b/packages/constraint-solver/solver.js @@ -424,8 +424,8 @@ CS.Solver.prototype.minimize = async function (step, options) { self.setSolution(await logic.minimizeWeightedSum( self.solution, optimized.costTerms, optimized.costWeights, { progress: async function (status, cost) { - if (self.options.nudge) { - await self.options.nudge(); + if (self.options.yield) { + await self.options.yield(); } if (DEBUG) { if (status === 'improving') { diff --git a/packages/meteor/asl_helpers_test.js b/packages/meteor/asl_helpers_test.js deleted file mode 100644 index 6944dd4822..0000000000 --- a/packages/meteor/asl_helpers_test.js +++ /dev/null @@ -1,74 +0,0 @@ -// -// Tinytest.addAsync("asynchronous - queue", async function (test, onComplete) { -// var q = new Meteor._AsynchronousQueue(); -// var output = []; -// var pusher = function (n) { -// return function () { -// output.push(n); -// }; -// }; -// var outputIsUpTo = function (n) { -// var range = []; -// for (var i = 1; i <= n; ++i) { -// range.push(i); -// } -// test.equal(output, range); -// }; -// const promises = []; -// // Queue a task. It cannot run until we yield. -// console.log('xxxx'); -// promises.push(q.queueTask(pusher(1))); -// -// outputIsUpTo(0); -// // Run another task. After queueing it, the fiber constructed here will yield -// // back to this outer function. No task can have run yet since the main test -// // fiber still will not have yielded. -// // var runTask2Done = false; -// // await q.runTask(pusher(2)); -// // runTask2Done = true; -// // outputIsUpTo(0); -// // test.isFalse(runTask2Done); -// -// // Queue a third task. Still no outer yields, so still no runs. -// promises.push(q.queueTask(function () { -// output.push(3); -// // This task gets queued once we actually start running functions, which -// // isn't until the runTask(pusher(4)), so it gets queued after Task #4. -// promises.push(q.queueTask(pusher(5))); -// })); -// -// console.log({promises}); -// outputIsUpTo(0); -// test.isFalse(runTask2Done); -// -// // Run a task and block for it to be done. All queued tasks up to this one -// // will now be run. -// await q.runTask(pusher(4)); -// outputIsUpTo(4); -// test.isTrue(runTask2Done); -// -// // Task #5 is still in the queue. Run another task synchronously. -// await q.runTask(pusher(6)); -// outputIsUpTo(6); -// -// // Queue a task that throws. It'll write some debug output, but that's it. -// Meteor._suppress_log(1); -// await q.queueTask(function () { -// throw new Error("bla"); -// }); -// // let it run. -// await q.runTask(pusher(7)); -// outputIsUpTo(7); -// -// // Run a task that throws. It should throw from runTask. -// Meteor._suppress_log(1); -// test.throws(async function () { -// try { -// await q.runTask(function () { -// throw new Error("this is thrown"); -// }); -// } catch (e) { -// console.log({e}); -// } -// }); -// }); diff --git a/packages/meteor/dynamics_browser.js b/packages/meteor/dynamics_browser.js index 6a05f0bd94..89373c9bc0 100644 --- a/packages/meteor/dynamics_browser.js +++ b/packages/meteor/dynamics_browser.js @@ -82,7 +82,3 @@ Meteor.bindEnvironment = function (func, onException, _this) { return ret; }; }; - -Meteor._nodeCodeMustBeInFiber = function () { - // no-op on browser -}; diff --git a/packages/meteor/dynamics_nodejs.js b/packages/meteor/dynamics_nodejs.js index 8122d286d3..df13a7f8e2 100644 --- a/packages/meteor/dynamics_nodejs.js +++ b/packages/meteor/dynamics_nodejs.js @@ -1,13 +1,10 @@ -// Implementation of dynamic scoping, for use on the server - with Fibers or AsyncLocalStorage +// Implementation of dynamic scoping, for use on the server with AsyncLocalStorage let nextSlot = 0; let callAsyncMethodRunning = false; const CURRENT_VALUE_KEY_NAME = 'currentValue'; const SLOT_CALL_KEY = 'slotCall'; -// NO-OP -Meteor._nodeCodeMustBeInFiber = function() {}; - class EnvironmentVariableAsync { constructor() { this.slot = nextSlot++; diff --git a/tools/console/console.js b/tools/console/console.js index b3d3ae04e2..2241495271 100644 --- a/tools/console/console.js +++ b/tools/console/console.js @@ -683,20 +683,19 @@ class Console extends ConsoleBase { // consuming lots of CPU without yielding is especially bad. // Other IO/network tasks will stall, and you can't even kill the process! // - // Within any code that may burn CPU for too long, call `Console.nudge()`. - // If it's been a while since your last yield, your Fiber will sleep momentarily. + // Within any code that may burn CPU for too long, call `Console.yield()`. // It will also update the spinner if there is one and it's been a while. - // The caller should be OK with yielding --- it has to be in a Fiber and it can't be - // anything that depends for correctness on not yielding. You can also call nudge(false) + // The caller should be OK with yielding --- it can't be + // anything that depends for correctness on not yielding. You can also call Console.nudge() // if you just want to update the spinner and not yield, but you should avoid this. - // TODO [fibers] -> Check here - consider this comment https://github.com/meteor/meteor/pull/12471/files#r1089560766 - async nudge(canYield) { + nudge() { if (this._statusPoller) { this._statusPoller.statusPoll(); } - if (canYield === undefined || canYield === true) { - await this._throttledYield.yield(); - } + } + async yield() { + this.nudge(); + await this._throttledYield.yield(); } // Initializes and returns a new ConsoleOptions object. Takes in the following diff --git a/tools/console/progress.ts b/tools/console/progress.ts index f6c5990cb1..f68f839482 100644 --- a/tools/console/progress.ts +++ b/tools/console/progress.ts @@ -45,8 +45,7 @@ export class Progress { return "Progress [state=" + JSON.stringify(this.state) + "]"; } - // TODO [fibers] - check if this can be really be async. Consider this comment https://github.com/meteor/meteor/pull/12471/files#r1089318098 - async reportProgressDone() { + reportProgressDone() { const state = { ...this.selfState, done: true, @@ -59,7 +58,7 @@ export class Progress { state.current = state.end; } - await this.reportProgress(state); + this.reportProgress(state); } // Tries to determine which is the 'current' job in the tree @@ -139,15 +138,15 @@ export class Progress { } // Receives a state report indicating progress of self - async reportProgress(state: ProgressState) { + reportProgress(state: ProgressState) { this.selfState = state; this.updateTotalState(); // Nudge the spinner/progress bar, but don't yield (might not be safe to yield) const { Console } = require("./console.js"); - // TODO [fibers] review this call. Consider this comment https://github.com/meteor/meteor/pull/12471/files#r1089316971 - await Console.nudge(false); + + Console.nudge(); this.notifyState(); } diff --git a/tools/isobuild/compiler.js b/tools/isobuild/compiler.js index d9ce37a067..97c899d795 100644 --- a/tools/isobuild/compiler.js +++ b/tools/isobuild/compiler.js @@ -569,7 +569,7 @@ api.addAssets('${relPath}', 'client').`); } else { watchSet.addFile(absPath, hash); } - await Console.nudge(true); + await Console.yield(); if (classification.type === "meteor-ignore") { // Return after watching .meteorignore files but before adding them diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index 31be03ed33..f56d08b237 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -801,7 +801,10 @@ Object.assign(Isopack.prototype, { }, nudge: function () { - return Console.nudge(true); + Console.nudge(); + }, + yield: function () { + return Console.yield(); }, convertToOSPath: files.convertToOSPath, diff --git a/tools/project-context.js b/tools/project-context.js index fc16fa5c44..93b64d47e1 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -947,8 +947,8 @@ Object.assign(ProjectContext.prototype, { const { ConstraintSolver } = await loadIsopackage('constraint-solver'); return new ConstraintSolver.PackagesResolver(this.projectCatalog, { - nudge() { - return Console.nudge(true); + yield() { + return Console.yield(); }, Profile: Profile, resultCache: this._resolverResultCache diff --git a/tools/utils/buildmessage.js b/tools/utils/buildmessage.js index f253dec4e9..1364b0e148 100644 --- a/tools/utils/buildmessage.js +++ b/tools/utils/buildmessage.js @@ -210,10 +210,10 @@ var reportProgress = function (state) { } }; -var reportProgressDone = async function () { +var reportProgressDone = function () { var progress = currentProgress.get(); if (progress) { - await progress.reportProgressDone(); + progress.reportProgressDone(); } }; @@ -283,7 +283,7 @@ async function capture(options, f) { } catch (e) { console.error(e); } finally { - await progress.reportProgressDone(); + progress.reportProgressDone(); resetFns.forEach(fn => fn()); @@ -356,7 +356,7 @@ async function enterJob(options, f) { try { return await f(); } finally { - await progress.reportProgressDone(); + progress.reportProgressDone(); while (resetFns.length) { await resetFns.pop()(); @@ -388,7 +388,7 @@ async function enterJob(options, f) { try { return await f(); } finally { - await progress.reportProgressDone(); + progress.reportProgressDone(); while (resetFns.length) { await resetFns.pop()(); diff --git a/tools/utils/http-helpers.js b/tools/utils/http-helpers.js index 49c14dc67b..68475b8492 100644 --- a/tools/utils/http-helpers.js +++ b/tools/utils/http-helpers.js @@ -363,7 +363,7 @@ Object.assign(exports, { } if (promise) { - return promise.finally(async () => progress && await progress.reportProgressDone()); + return promise.finally(() => progress && progress.reportProgressDone()); } else { return req; }