From da2ae29ddbbabdc0d54f7abd7416fbee9826ee65 Mon Sep 17 00:00:00 2001 From: Renan Castro Date: Mon, 24 Jan 2022 19:03:41 -0300 Subject: [PATCH 01/20] 5.0.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 398b123..3e9ac2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.0", + "version": "5.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fbd62f6..c04a400 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.0", + "version": "5.0.1", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber", From a6bd937ad876b95e803c4833ee5cefd5b293cbdb Mon Sep 17 00:00:00 2001 From: denihs Date: Tue, 9 Aug 2022 09:38:38 -0400 Subject: [PATCH 02/20] Fixing package.json to the right version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c04a400..f0d749c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.1", + "version": "5.0.2", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber", From 0b41197a766e8c1ea4834b561f70616fc4997ba6 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Mon, 26 Sep 2022 11:15:49 -0400 Subject: [PATCH 03/20] initial work to get async resource working correctly --- fibers.js | 2 +- fibers_async.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 fibers_async.js diff --git a/fibers.js b/fibers.js index 3229dad..851bbe0 100644 --- a/fibers.js +++ b/fibers.js @@ -23,7 +23,7 @@ if (process.fiberLib) { throw new Error('Missing binary. See message above.'); } - setupAsyncHacks(module.exports); + //setupAsyncHacks(module.exports); } function setupAsyncHacks(Fiber) { diff --git a/fibers_async.js b/fibers_async.js new file mode 100644 index 0000000..d8f0a0a --- /dev/null +++ b/fibers_async.js @@ -0,0 +1,60 @@ +const { AsyncResource } = require('async_hooks'); +const { timeStamp } = require('console'); +const _Fiber = require('./fibers.js'); + +const weakMap = new WeakMap(); +const Fiber = function Fiber(...args) { + if (!(this instanceof Fiber)) { + return new Fiber(...args); + } + + const _private = { + _ar: new AsyncResource('Fiber'), + _fiber: _Fiber(...args) + }; + weakMap.set(this, _private); + _private._fiber._f = this; + return this; +}; + +Fiber.__proto__ = _Fiber; + +Object.defineProperty(Fiber, 'current', { + get() { + return _Fiber.current && _Fiber.current._f; + } +}) + +_Fiber[Symbol.hasInstance] = function(obj) { + // hacky + return obj instanceof Fiber || obj.run; +}; + +module.exports = Fiber; +Fiber.prototype = { + __proto__: Fiber, + get current() { + return _Fiber.current._f; + }, + + yield() { + return _Fiber.yield(...args); + }, + + get _ar() { + return weakMap.get(this)._ar; + }, + + // because of promise fiber pool, we want this. + set _ar(ar) { + return weakMap.get(this)._ar = ar; + }, + + get _fiber() { + return weakMap.get(this)._fiber; + }, + + run(...args) { + return this._ar.runInAsyncScope(() => this._fiber.run(...args)); + } +} diff --git a/package.json b/package.json index f0d749c..7ecebfe 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ ], "homepage": "https://github.com/laverdet/node-fibers", "author": "Marcel Laverdet (https://github.com/laverdet/)", - "main": "fibers", + "main": "fibers_async", "scripts": { "install": "node build.js || nodejs build.js", "test": "node test.js || nodejs test.js" From a66d37e6bd77bb7c0f1a5dfe56e25078a8438a0a Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Sat, 8 Oct 2022 12:02:34 -0400 Subject: [PATCH 04/20] fix throw into --- fibers_async.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fibers_async.js b/fibers_async.js index d8f0a0a..8a5e9c7 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -56,5 +56,9 @@ Fiber.prototype = { run(...args) { return this._ar.runInAsyncScope(() => this._fiber.run(...args)); + }, + + throwInto(...args) { + return this._ar.runInAsyncScope(() => this._fiber.throwInto(...args)); } } From 9f02b7c20f872b2871fe7f3b7b73099e903bfed7 Mon Sep 17 00:00:00 2001 From: Zack Date: Thu, 13 Oct 2022 18:30:21 -0400 Subject: [PATCH 05/20] Update future.js --- future.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/future.js b/future.js index 48cf7dd..6903f0d 100644 --- a/future.js +++ b/future.js @@ -1,5 +1,5 @@ "use strict"; -var Fiber = require('./fibers'); +var Fiber = require('./fibers_async'); var util = require('util'); module.exports = Future; Function.prototype.future = function(detach) { From f3457b53ef83bcf8e0a7616c870e9e0ddb6ea5f3 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Wed, 19 Oct 2022 17:27:30 -0400 Subject: [PATCH 06/20] attempt to get yield working --- fibers_async.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index 8a5e9c7..23b4846 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -1,4 +1,4 @@ -const { AsyncResource } = require('async_hooks'); +const { AsyncResource, executionAsyncResource } = require('async_hooks'); const { timeStamp } = require('console'); const _Fiber = require('./fibers.js'); @@ -9,7 +9,7 @@ const Fiber = function Fiber(...args) { } const _private = { - _ar: new AsyncResource('Fiber'), + _ar: new AsyncResource('Fiber'), _fiber: _Fiber(...args) }; weakMap.set(this, _private); @@ -30,6 +30,13 @@ _Fiber[Symbol.hasInstance] = function(obj) { return obj instanceof Fiber || obj.run; }; +Fiber.yield = function(...args) { + const current = Fiber.current; + const _ar = current._ar; + const ret = _ar.runInAsyncScope(() => _Fiber.yield(...args)); + return ret; +}; + module.exports = Fiber; Fiber.prototype = { __proto__: Fiber, @@ -37,8 +44,9 @@ Fiber.prototype = { return _Fiber.current._f; }, - yield() { - return _Fiber.yield(...args); + yield(...args) { + const ret = Fiber.yield(...args); + return ret; }, get _ar() { From 1dfbfff4175d7fbecb849578c02ccc42db0cebd2 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Wed, 19 Oct 2022 17:30:04 -0400 Subject: [PATCH 07/20] attempt to get yield working --- fibers_async.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index 23b4846..c8801da 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -31,9 +31,9 @@ _Fiber[Symbol.hasInstance] = function(obj) { }; Fiber.yield = function(...args) { - const current = Fiber.current; - const _ar = current._ar; - const ret = _ar.runInAsyncScope(() => _Fiber.yield(...args)); + const _ar = Fiber.current._ar; + const ret = _Fiber.yield(...args); + const _arNext = Fiber.current._ar; return ret; }; From f20bfcabf8f4c61de5269bf77ee1ec7b5ae2e778 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Wed, 19 Oct 2022 17:31:36 -0400 Subject: [PATCH 08/20] attempt to get yield working --- fibers_async.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fibers_async.js b/fibers_async.js index c8801da..fb5f098 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -32,8 +32,10 @@ _Fiber[Symbol.hasInstance] = function(obj) { Fiber.yield = function(...args) { const _ar = Fiber.current._ar; + const _ar1 = executionAsyncResource(); const ret = _Fiber.yield(...args); const _arNext = Fiber.current._ar; + const _arNext1 = executionAsyncResource(); return ret; }; From 8db88f6aa23dc8013ec0ac546966d67253d06e43 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Wed, 19 Oct 2022 17:34:23 -0400 Subject: [PATCH 09/20] attempt to get yield working --- fibers_async.js | 1 + 1 file changed, 1 insertion(+) diff --git a/fibers_async.js b/fibers_async.js index fb5f098..f4c8519 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -36,6 +36,7 @@ Fiber.yield = function(...args) { const ret = _Fiber.yield(...args); const _arNext = Fiber.current._ar; const _arNext1 = executionAsyncResource(); + Fiber.current._ar = _arNext1; return ret; }; From 8af722f8c4924567c8a0619df23b68d109b7676b Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Fri, 4 Nov 2022 15:15:33 -0400 Subject: [PATCH 10/20] test with thread based fibers --- binding.gyp | 10 +--- fibers.js | 133 +---------------------------------------------- fibers_async.js | 25 +++++---- fibers_sync.js | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 151 deletions(-) create mode 100644 fibers_sync.js diff --git a/binding.gyp b/binding.gyp index 2289325..1b13fb9 100644 --- a/binding.gyp +++ b/binding.gyp @@ -41,15 +41,7 @@ ['OS == "linux"', { 'cflags_c': [ '-std=gnu11' ], - 'variables': { - 'USE_MUSL': '&1 | head -n1 | grep "musl" | wc -l)', - }, - 'conditions': [ - ['<(USE_MUSL) == 1', - {'defines': ['CORO_ASM', '__MUSL__']}, - {'defines': ['CORO_UCONTEXT']} - ], - ], + 'defines': ['CORO_PTHREAD'], }, ], ['OS == "solaris" or OS == "sunos" or OS == "freebsd" or OS == "aix"', {'defines': ['CORO_UCONTEXT']}], diff --git a/fibers.js b/fibers.js index 851bbe0..d79b849 100644 --- a/fibers.js +++ b/fibers.js @@ -1,132 +1 @@ -if (process.fiberLib) { - module.exports = process.fiberLib; -} else { - var fs = require('fs'), path = require('path'), detectLibc = require('detect-libc'); - - // Seed random numbers [gh-82] - Math.random(); - - // Look for binary for this platform - var modPath = path.join(__dirname, 'bin', process.platform+ '-'+ process.arch+ '-'+ process.versions.modules+ - ((process.platform === 'linux') ? '-'+ detectLibc.family : ''), 'fibers'); - try { - // Pull in fibers implementation - process.fiberLib = module.exports = require(modPath).Fiber; - } catch (ex) { - // No binary! - console.error( - '## There is an issue with `node-fibers` ##\n'+ - '`'+ modPath+ '.node` is missing.\n\n'+ - 'Try running this to fix the issue: '+ process.execPath+ ' '+ __dirname.replace(' ', '\\ ')+ '/build' - ); - console.error(ex.stack || ex.message || ex); - throw new Error('Missing binary. See message above.'); - } - - //setupAsyncHacks(module.exports); -} - -function setupAsyncHacks(Fiber) { - // Older (or newer?) versions of node may not support this API - try { - var aw = process.binding('async_wrap'); - var getAsyncIdStackSize; - - if (aw.asyncIdStackSize instanceof Function) { - getAsyncIdStackSize = aw.asyncIdStackSize; - } else if (aw.constants.kStackLength !== undefined) { - getAsyncIdStackSize = function(kStackLength) { - return function() { - return aw.async_hook_fields[kStackLength]; - }; - }(aw.constants.kStackLength); - } else { - throw new Error('Couldn\'t figure out how to get async stack size'); - } - - var popAsyncContext = aw.popAsyncContext || aw.popAsyncIds; - var pushAsyncContext = aw.pushAsyncContext || aw.pushAsyncIds; - if (!popAsyncContext || !pushAsyncContext) { - throw new Error('Push/pop do not exist'); - } - - var kExecutionAsyncId; - if (aw.constants.kExecutionAsyncId === undefined) { - kExecutionAsyncId = aw.constants.kCurrentAsyncId; - } else { - kExecutionAsyncId = aw.constants.kExecutionAsyncId; - } - var kTriggerAsyncId; - if (aw.constants.kTriggerAsyncId === undefined) { - kTriggerAsyncId = aw.constants.kCurrentTriggerId; - } else { - kTriggerAsyncId = aw.constants.kTriggerAsyncId; - } - - var asyncIds = aw.async_id_fields || aw.async_uid_fields; - - function getAndClearStack() { - var ii = getAsyncIdStackSize(); - var stack = new Array(ii); - for (; ii > 0; --ii) { - var asyncId = asyncIds[kExecutionAsyncId]; - stack[ii - 1] = { - asyncId: asyncId, - triggerId: asyncIds[kTriggerAsyncId], - }; - popAsyncContext(asyncId); - } - return stack; - } - - function restoreStack(stack) { - for (var ii = 0; ii < stack.length; ++ii) { - pushAsyncContext(stack[ii].asyncId, stack[ii].triggerId); - } - } - - function logUsingFibers(fibersMethod) { - const logUseFibersLevel = +(process.env.ENABLE_LOG_USE_FIBERS || 0); - - if (!logUseFibersLevel) return; - - if (logUseFibersLevel === 1) { - console.warn(`[FIBERS_LOG] Using ${fibersMethod}.`); - return; - } - - const { LOG_USE_FIBERS_INCLUDE_IN_PATH } = process.env; - const stackFromError = new Error(`[FIBERS_LOG] Using ${fibersMethod}.`).stack; - - if ( - !LOG_USE_FIBERS_INCLUDE_IN_PATH || - stackFromError.includes(LOG_USE_FIBERS_INCLUDE_IN_PATH) - ) { - console.warn(stackFromError); - } - } - - function wrapFunction(fn, fibersMethod) { - return function () { - logUsingFibers(fibersMethod); - var stack = getAndClearStack(); - try { - return fn.apply(this, arguments); - } finally { - restoreStack(stack); - } - }; - } - - // Monkey patch methods which may long jump - Fiber.yield = wrapFunction(Fiber.yield, "Fiber.yield"); - Fiber.prototype.run = wrapFunction(Fiber.prototype.run, "Fiber.run"); - Fiber.prototype.throwInto = wrapFunction( - Fiber.prototype.throwInto, - "Fiber.throwInto" - ); - - } catch (err) { - return; - } -} +module.exports = require('./fibers_async.js'); diff --git a/fibers_async.js b/fibers_async.js index f4c8519..d0cd4ad 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -1,9 +1,9 @@ const { AsyncResource, executionAsyncResource } = require('async_hooks'); const { timeStamp } = require('console'); -const _Fiber = require('./fibers.js'); +const _Fiber = require('./fibers_sync.js'); -const weakMap = new WeakMap(); -const Fiber = function Fiber(...args) { +const weakMap = new Map(); +function Fiber(...args) { if (!(this instanceof Fiber)) { return new Fiber(...args); } @@ -31,13 +31,8 @@ _Fiber[Symbol.hasInstance] = function(obj) { }; Fiber.yield = function(...args) { - const _ar = Fiber.current._ar; - const _ar1 = executionAsyncResource(); - const ret = _Fiber.yield(...args); - const _arNext = Fiber.current._ar; - const _arNext1 = executionAsyncResource(); - Fiber.current._ar = _arNext1; - return ret; + return _Fiber.yield(...args); + // return Fiber.current._ar.runInAsyncScope(() => _Fiber.yield(...args)); }; module.exports = Fiber; @@ -65,11 +60,21 @@ Fiber.prototype = { return weakMap.get(this)._fiber; }, + get started() { + return this._fiber.started; + }, + run(...args) { return this._ar.runInAsyncScope(() => this._fiber.run(...args)); }, throwInto(...args) { return this._ar.runInAsyncScope(() => this._fiber.throwInto(...args)); + }, + + reset(...args) { + return this._ar.runInAsyncScope(() => this._fiber.reset(...args)); } } + +// _Fiber.setupAsyncHacks(Fiber); diff --git a/fibers_sync.js b/fibers_sync.js new file mode 100644 index 0000000..2ff71f6 --- /dev/null +++ b/fibers_sync.js @@ -0,0 +1,134 @@ +if (process.fiberLib) { + module.exports = process.fiberLib; +} else { + var fs = require('fs'), path = require('path'), detectLibc = require('detect-libc'); + + // Seed random numbers [gh-82] + Math.random(); + + // Look for binary for this platform + var modPath = path.join(__dirname, 'bin', process.platform+ '-'+ process.arch+ '-'+ process.versions.modules+ + ((process.platform === 'linux') ? '-'+ detectLibc.family : ''), 'fibers'); + try { + // Pull in fibers implementation + process.fiberLib = module.exports = require(modPath).Fiber; + } catch (ex) { + // No binary! + console.error( + '## There is an issue with `node-fibers` ##\n'+ + '`'+ modPath+ '.node` is missing.\n\n'+ + 'Try running this to fix the issue: '+ process.execPath+ ' '+ __dirname.replace(' ', '\\ ')+ '/build' + ); + console.error(ex.stack || ex.message || ex); + throw new Error('Missing binary. See message above.'); + } + + // setupAsyncHacks(module.exports); +} + +function setupAsyncHacks(Fiber) { + // Older (or newer?) versions of node may not support this API + try { + var aw = process.binding('async_wrap'); + var getAsyncIdStackSize; + + if (aw.asyncIdStackSize instanceof Function) { + getAsyncIdStackSize = aw.asyncIdStackSize; + } else if (aw.constants.kStackLength !== undefined) { + getAsyncIdStackSize = function(kStackLength) { + return function() { + return aw.async_hook_fields[kStackLength]; + }; + }(aw.constants.kStackLength); + } else { + throw new Error('Couldn\'t figure out how to get async stack size'); + } + + var popAsyncContext = aw.popAsyncContext || aw.popAsyncIds; + var pushAsyncContext = aw.pushAsyncContext || aw.pushAsyncIds; + if (!popAsyncContext || !pushAsyncContext) { + throw new Error('Push/pop do not exist'); + } + + var kExecutionAsyncId; + if (aw.constants.kExecutionAsyncId === undefined) { + kExecutionAsyncId = aw.constants.kCurrentAsyncId; + } else { + kExecutionAsyncId = aw.constants.kExecutionAsyncId; + } + var kTriggerAsyncId; + if (aw.constants.kTriggerAsyncId === undefined) { + kTriggerAsyncId = aw.constants.kCurrentTriggerId; + } else { + kTriggerAsyncId = aw.constants.kTriggerAsyncId; + } + + var asyncIds = aw.async_id_fields || aw.async_uid_fields; + + function getAndClearStack() { + var ii = getAsyncIdStackSize(); + var stack = new Array(ii); + for (; ii > 0; --ii) { + var asyncId = asyncIds[kExecutionAsyncId]; + stack[ii - 1] = { + asyncId: asyncId, + triggerId: asyncIds[kTriggerAsyncId], + }; + popAsyncContext(asyncId); + } + return stack; + } + + function restoreStack(stack) { + for (var ii = 0; ii < stack.length; ++ii) { + pushAsyncContext(stack[ii].asyncId, stack[ii].triggerId); + } + } + + function logUsingFibers(fibersMethod) { + const logUseFibersLevel = +(process.env.ENABLE_LOG_USE_FIBERS || 0); + + if (!logUseFibersLevel) return; + + if (logUseFibersLevel === 1) { + console.warn(`[FIBERS_LOG] Using ${fibersMethod}.`); + return; + } + + const { LOG_USE_FIBERS_INCLUDE_IN_PATH } = process.env; + const stackFromError = new Error(`[FIBERS_LOG] Using ${fibersMethod}.`).stack; + + if ( + !LOG_USE_FIBERS_INCLUDE_IN_PATH || + stackFromError.includes(LOG_USE_FIBERS_INCLUDE_IN_PATH) + ) { + console.warn(stackFromError); + } + } + + function wrapFunction(fn, fibersMethod) { + return function () { + logUsingFibers(fibersMethod); + var stack = getAndClearStack(); + try { + return fn.apply(this, arguments); + } finally { + restoreStack(stack); + } + }; + } + + // Monkey patch methods which may long jump + Fiber.yield = wrapFunction(Fiber.yield, "Fiber.yield"); + Fiber.prototype.run = wrapFunction(Fiber.prototype.run, "Fiber.run"); + Fiber.prototype.throwInto = wrapFunction( + Fiber.prototype.throwInto, + "Fiber.throwInto" + ); + + } catch (err) { + return; + } +} + +module.exports.setupAsyncHacks = setupAsyncHacks; From ab9270cef9eaf3f92543644ffbbe7f92f21aebca Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Fri, 4 Nov 2022 16:08:53 -0400 Subject: [PATCH 11/20] working correctly --- fibers_async.js | 30 ++++++++++++++++++++---------- fibers_sync.js | 5 ++++- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index d0cd4ad..8d3fa28 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -1,17 +1,24 @@ -const { AsyncResource, executionAsyncResource } = require('async_hooks'); +const { AsyncResource, executionAsyncResource, executionAsyncId } = require('async_hooks'); const { timeStamp } = require('console'); +const aw = process.binding('async_wrap'); const _Fiber = require('./fibers_sync.js'); const weakMap = new Map(); -function Fiber(...args) { +function Fiber(fn, ...args) { if (!(this instanceof Fiber)) { - return new Fiber(...args); + return new Fiber(fn, ...args); } + const ar = new AsyncResource('Fiber'); + + const actualFn = (...fnArgs) => { + return ar.runInAsyncScope(() => fn(...fnArgs)); + } const _private = { - _ar: new AsyncResource('Fiber'), - _fiber: _Fiber(...args) + _ar: ar, + _fiber: _Fiber(actualFn, ...args) }; + weakMap.set(this, _private); _private._fiber._f = this; return this; @@ -31,8 +38,8 @@ _Fiber[Symbol.hasInstance] = function(obj) { }; Fiber.yield = function(...args) { + const ar = Fiber.current._ar; return _Fiber.yield(...args); - // return Fiber.current._ar.runInAsyncScope(() => _Fiber.yield(...args)); }; module.exports = Fiber; @@ -65,16 +72,19 @@ Fiber.prototype = { }, run(...args) { - return this._ar.runInAsyncScope(() => this._fiber.run(...args)); + return this._fiber.run(...args); + //return this._ar.runInAsyncScope(() => this._fiber.run(...args)); }, throwInto(...args) { - return this._ar.runInAsyncScope(() => this._fiber.throwInto(...args)); + return this._fiber.throwInto(...args); + //return this._ar.runInAsyncScope(() => this._fiber.throwInto(...args)); }, reset(...args) { - return this._ar.runInAsyncScope(() => this._fiber.reset(...args)); + return this._fiber.reset(...args); + //return this._ar.runInAsyncScope(() => this._fiber.reset(...args)); } } -// _Fiber.setupAsyncHacks(Fiber); +//_Fiber.setupAsyncHacks(Fiber); diff --git a/fibers_sync.js b/fibers_sync.js index 2ff71f6..24493ba 100644 --- a/fibers_sync.js +++ b/fibers_sync.js @@ -23,13 +23,14 @@ if (process.fiberLib) { throw new Error('Missing binary. See message above.'); } - // setupAsyncHacks(module.exports); + setupAsyncHacks(module.exports); } function setupAsyncHacks(Fiber) { // Older (or newer?) versions of node may not support this API try { var aw = process.binding('async_wrap'); + var ah = require('async_hooks'); var getAsyncIdStackSize; if (aw.asyncIdStackSize instanceof Function) { @@ -71,6 +72,7 @@ function setupAsyncHacks(Fiber) { for (; ii > 0; --ii) { var asyncId = asyncIds[kExecutionAsyncId]; stack[ii - 1] = { + asyncResource: ah.executionAsyncResource(), asyncId: asyncId, triggerId: asyncIds[kTriggerAsyncId], }; @@ -82,6 +84,7 @@ function setupAsyncHacks(Fiber) { function restoreStack(stack) { for (var ii = 0; ii < stack.length; ++ii) { pushAsyncContext(stack[ii].asyncId, stack[ii].triggerId); + aw.execution_async_resources.push(stack[ii].asyncResource); } } From 3229cdda21052a36afdebcd88facfc83a24f24bb Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Fri, 4 Nov 2022 18:00:01 -0400 Subject: [PATCH 12/20] cleanup --- fibers_async.js | 32 ++------------------------------ fibers_sync.js | 2 -- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index 8d3fa28..149220d 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -1,5 +1,4 @@ -const { AsyncResource, executionAsyncResource, executionAsyncId } = require('async_hooks'); -const { timeStamp } = require('console'); +const { AsyncResource } = require('async_hooks'); const aw = process.binding('async_wrap'); const _Fiber = require('./fibers_sync.js'); @@ -15,7 +14,6 @@ function Fiber(fn, ...args) { return ar.runInAsyncScope(() => fn(...fnArgs)); } const _private = { - _ar: ar, _fiber: _Fiber(actualFn, ...args) }; @@ -25,6 +23,7 @@ function Fiber(fn, ...args) { }; Fiber.__proto__ = _Fiber; +Fiber.prototype = _Fiber.prototype; Object.defineProperty(Fiber, 'current', { get() { @@ -37,31 +36,9 @@ _Fiber[Symbol.hasInstance] = function(obj) { return obj instanceof Fiber || obj.run; }; -Fiber.yield = function(...args) { - const ar = Fiber.current._ar; - return _Fiber.yield(...args); -}; - module.exports = Fiber; Fiber.prototype = { __proto__: Fiber, - get current() { - return _Fiber.current._f; - }, - - yield(...args) { - const ret = Fiber.yield(...args); - return ret; - }, - - get _ar() { - return weakMap.get(this)._ar; - }, - - // because of promise fiber pool, we want this. - set _ar(ar) { - return weakMap.get(this)._ar = ar; - }, get _fiber() { return weakMap.get(this)._fiber; @@ -73,18 +50,13 @@ Fiber.prototype = { run(...args) { return this._fiber.run(...args); - //return this._ar.runInAsyncScope(() => this._fiber.run(...args)); }, throwInto(...args) { return this._fiber.throwInto(...args); - //return this._ar.runInAsyncScope(() => this._fiber.throwInto(...args)); }, reset(...args) { return this._fiber.reset(...args); - //return this._ar.runInAsyncScope(() => this._fiber.reset(...args)); } } - -//_Fiber.setupAsyncHacks(Fiber); diff --git a/fibers_sync.js b/fibers_sync.js index 24493ba..9baf8af 100644 --- a/fibers_sync.js +++ b/fibers_sync.js @@ -133,5 +133,3 @@ function setupAsyncHacks(Fiber) { return; } } - -module.exports.setupAsyncHacks = setupAsyncHacks; From d6788269d7886bc1d4a4d287bc59a3e1cc93779b Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Sat, 12 Nov 2022 11:09:40 -0500 Subject: [PATCH 13/20] closer to correct --- fibers_async.js | 19 ++++++++++++------- future.js | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index 149220d..6c1fc1e 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -7,14 +7,15 @@ function Fiber(fn, ...args) { if (!(this instanceof Fiber)) { return new Fiber(fn, ...args); } - - const ar = new AsyncResource('Fiber'); - - const actualFn = (...fnArgs) => { - return ar.runInAsyncScope(() => fn(...fnArgs)); - } + const actualFn = fn; /*(...fnArgs) => { + return globalAr.runInAsyncScope(() => { + const ar = new AsyncResource('Fiber'); + return ar.runInAsyncScope(() => fn(...fnArgs)); + }); + };*/ const _private = { - _fiber: _Fiber(actualFn, ...args) + _fiber: _Fiber(actualFn, ...args), + _ar: new AsyncResource('Fiber'), }; weakMap.set(this, _private); @@ -48,6 +49,10 @@ Fiber.prototype = { return this._fiber.started; }, + runInAsyncScope(fn) { + return weakMap.get(this)._ar.runInAsyncScope(fn); + }, + run(...args) { return this._fiber.run(...args); }, diff --git a/future.js b/future.js index 6903f0d..48cf7dd 100644 --- a/future.js +++ b/future.js @@ -1,5 +1,5 @@ "use strict"; -var Fiber = require('./fibers_async'); +var Fiber = require('./fibers'); var util = require('util'); module.exports = Future; Function.prototype.future = function(detach) { From 1c1f3131f815b2f13e1ee52fd8a16326370e0800 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Fri, 2 Dec 2022 11:19:09 -0500 Subject: [PATCH 14/20] use weakmap --- fibers_async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fibers_async.js b/fibers_async.js index 6c1fc1e..db146b5 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -2,7 +2,7 @@ const { AsyncResource } = require('async_hooks'); const aw = process.binding('async_wrap'); const _Fiber = require('./fibers_sync.js'); -const weakMap = new Map(); +const weakMap = new WeakMap(); function Fiber(fn, ...args) { if (!(this instanceof Fiber)) { return new Fiber(fn, ...args); From f1a3fe5e096bb851d20f17ffa3abae31d65777db Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Fri, 21 Apr 2023 07:49:39 -0400 Subject: [PATCH 15/20] cleanup of fibers_async, enable node 16 in more envs, --- .npmrc | 2 ++ fibers_async.js | 58 +++++++++--------------------------------------- package.json | 2 +- src/coroutine.cc | 2 +- 4 files changed, 15 insertions(+), 49 deletions(-) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..c9523cd --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +always-auth = true +registry = https://verdaccio.staging.qualia.io/ diff --git a/fibers_async.js b/fibers_async.js index db146b5..902d8f5 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -1,26 +1,12 @@ const { AsyncResource } = require('async_hooks'); -const aw = process.binding('async_wrap'); const _Fiber = require('./fibers_sync.js'); -const weakMap = new WeakMap(); +const asyncResourceWeakMap = new WeakMap(); function Fiber(fn, ...args) { - if (!(this instanceof Fiber)) { - return new Fiber(fn, ...args); - } - const actualFn = fn; /*(...fnArgs) => { - return globalAr.runInAsyncScope(() => { - const ar = new AsyncResource('Fiber'); - return ar.runInAsyncScope(() => fn(...fnArgs)); - }); - };*/ - const _private = { - _fiber: _Fiber(actualFn, ...args), - _ar: new AsyncResource('Fiber'), - }; - - weakMap.set(this, _private); - _private._fiber._f = this; - return this; + const _fiber = _Fiber(fn, ...args); + const ar = new AsyncResource('Fiber'); + asyncResourceWeakMap.set(_fiber, ar); + return _fiber; }; Fiber.__proto__ = _Fiber; @@ -28,40 +14,18 @@ Fiber.prototype = _Fiber.prototype; Object.defineProperty(Fiber, 'current', { get() { - return _Fiber.current && _Fiber.current._f; + return _Fiber.current; } }) + +_Fiber.prototype.runInAsyncScope = function runInAsyncScope(fn) { + return asyncResourceWeakMap.get(this).runInAsyncScope(fn); +}; + _Fiber[Symbol.hasInstance] = function(obj) { // hacky return obj instanceof Fiber || obj.run; }; module.exports = Fiber; -Fiber.prototype = { - __proto__: Fiber, - - get _fiber() { - return weakMap.get(this)._fiber; - }, - - get started() { - return this._fiber.started; - }, - - runInAsyncScope(fn) { - return weakMap.get(this)._ar.runInAsyncScope(fn); - }, - - run(...args) { - return this._fiber.run(...args); - }, - - throwInto(...args) { - return this._fiber.throwInto(...args); - }, - - reset(...args) { - return this._fiber.reset(...args); - } -} diff --git a/package.json b/package.json index 7ecebfe..f2d6c02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.2", + "version": "5.0.2-2", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber", diff --git a/src/coroutine.cc b/src/coroutine.cc index 027744f..e89abdc 100644 --- a/src/coroutine.cc +++ b/src/coroutine.cc @@ -148,7 +148,7 @@ void Coroutine::init(v8::Isolate* isolate) { isolate_key = v8::internal::Isolate::isolate_key_; thread_data_key = v8::internal::Isolate::per_isolate_thread_data_key_; thread_id_key = v8::internal::Isolate::thread_id_key_; -#else +#elif !defined(CORO_PTHREAD) pthread_t thread; pthread_create(&thread, NULL, find_thread_id_key, isolate); pthread_join(thread, NULL); From 7e4fd6db662853ab1b9136bd95a419255192e2ca Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Thu, 22 Jun 2023 15:51:20 -0400 Subject: [PATCH 16/20] work with pthread in all envs --- binding.gyp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/binding.gyp b/binding.gyp index 1b13fb9..824ce58 100644 --- a/binding.gyp +++ b/binding.gyp @@ -57,8 +57,8 @@ ['target_arch == "arm64"', { # There's been problems getting real fibers working on arm - 'defines': ['CORO_UCONTEXT', '_XOPEN_SOURCE'], - 'defines!': ['CORO_PTHREAD', 'CORO_SJLJ', 'CORO_ASM'], + 'defines': ['CORO_PTHREAD'], + 'defines!': ['CORO_UCONTEXT', 'CORO_SJLJ', 'CORO_ASM'], }, ], ], From aa90689a6cbc001c56531c8cea8f910a68628dbd Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Thu, 22 Jun 2023 15:51:55 -0400 Subject: [PATCH 17/20] protect against duplicate imports --- fibers_async.js | 9 +++++++-- package.json | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index 902d8f5..321deb6 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -1,6 +1,11 @@ const { AsyncResource } = require('async_hooks'); const _Fiber = require('./fibers_sync.js'); - +if (_Fiber.Fiber) { + // if we were to mix'n'match import/require - we could end up with multiple copies of this + // it might also relate to weirdness of importing it from inside the shell/debugger + // it almost looks like the --preserve-symlinks is being ignored in the debugger/shell + module.exports = _Fiber.Fiber; +} const asyncResourceWeakMap = new WeakMap(); function Fiber(fn, ...args) { const _fiber = _Fiber(fn, ...args); @@ -28,4 +33,4 @@ _Fiber[Symbol.hasInstance] = function(obj) { return obj instanceof Fiber || obj.run; }; -module.exports = Fiber; +module.exports = _Fiber.Fiber = Fiber; diff --git a/package.json b/package.json index f2d6c02..0728a77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.2-2", + "version": "5.0.2-4", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber", From 0385a4f9bcd562a92ed205fad688ddcd87519727 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Thu, 29 Jun 2023 22:37:22 -0400 Subject: [PATCH 18/20] ensure the fiber run function always enters with an executionAsyncId() --- fibers_async.js | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fibers_async.js b/fibers_async.js index 321deb6..e360262 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -8,8 +8,9 @@ if (_Fiber.Fiber) { } const asyncResourceWeakMap = new WeakMap(); function Fiber(fn, ...args) { - const _fiber = _Fiber(fn, ...args); const ar = new AsyncResource('Fiber'); + const actualFn = (...args1) => ar.runInAsyncScope(() => fn(...args1)); + const _fiber = _Fiber(actualFn, ...args); asyncResourceWeakMap.set(_fiber, ar); return _fiber; }; diff --git a/package.json b/package.json index 0728a77..b39cd1c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.2-4", + "version": "5.0.2-5", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber", From 1e009604468565bdc9445b224cbde7fbedf9ab03 Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Wed, 5 Jul 2023 11:47:37 -0400 Subject: [PATCH 19/20] ensure the fiber clears _meteor_dynamics --- .npmrc | 2 +- fibers_async.js | 5 ++++- package.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.npmrc b/.npmrc index c9523cd..94059b8 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ always-auth = true -registry = https://verdaccio.staging.qualia.io/ +registry = https://verdaccio.prod-tools.qualia.io/ diff --git a/fibers_async.js b/fibers_async.js index e360262..9546a9d 100644 --- a/fibers_async.js +++ b/fibers_async.js @@ -9,7 +9,10 @@ if (_Fiber.Fiber) { const asyncResourceWeakMap = new WeakMap(); function Fiber(fn, ...args) { const ar = new AsyncResource('Fiber'); - const actualFn = (...args1) => ar.runInAsyncScope(() => fn(...args1)); + const actualFn = (...args1) => ar.runInAsyncScope(() => { + Fiber.current._meteor_dynamics = undefined; + fn(...args1); + }); const _fiber = _Fiber(actualFn, ...args); asyncResourceWeakMap.set(_fiber, ar); return _fiber; diff --git a/package.json b/package.json index b39cd1c..0002b8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.2-5", + "version": "5.0.2-6", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber", From 2d44319bc3dbc89fe4b3100426247721d4e1d13b Mon Sep 17 00:00:00 2001 From: Zack Newsham Date: Wed, 20 Sep 2023 16:55:48 -0400 Subject: [PATCH 20/20] push out env var access --- fibers_sync.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fibers_sync.js b/fibers_sync.js index 9baf8af..c8d76b2 100644 --- a/fibers_sync.js +++ b/fibers_sync.js @@ -88,8 +88,9 @@ function setupAsyncHacks(Fiber) { } } + const logUseFibersLevel = +(process.env.ENABLE_LOG_USE_FIBERS || 0); + const { LOG_USE_FIBERS_INCLUDE_IN_PATH } = process.env; function logUsingFibers(fibersMethod) { - const logUseFibersLevel = +(process.env.ENABLE_LOG_USE_FIBERS || 0); if (!logUseFibersLevel) return; @@ -98,7 +99,6 @@ function setupAsyncHacks(Fiber) { return; } - const { LOG_USE_FIBERS_INCLUDE_IN_PATH } = process.env; const stackFromError = new Error(`[FIBERS_LOG] Using ${fibersMethod}.`).stack; if ( diff --git a/package.json b/package.json index 0002b8f..22ee9b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.2-6", + "version": "5.0.2-7", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber",