From 1ee27b029db32012ba48cd4a2a744d73f59e6628 Mon Sep 17 00:00:00 2001 From: Gabriel Trujillo Date: Mon, 10 Oct 2022 20:04:45 -0500 Subject: [PATCH 1/2] Restored support for v.16 --- .vscode/launch.json | 20 ++++++++++++++++++++ package-lock.json | 11 ++++++++--- package.json | 4 ++-- src/main/eventsReducer.js | 15 +++++++++------ src/worker/asyncHook.js | 37 +++++++++++++++++++------------------ 5 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5b5b95b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "runtimeExecutable": "/Users/gabbytee/.nvm/versions/node/v16.17.1/bin/node", + "cwd":"${workspaceFolder}/Node-EventLoop-Visualizer-Server/", + "program": "${workspaceFolder}/Node-EventLoop-Visualizer-Server/index.js" + } + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a11b191..009e515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "requires": true, "packages": { "": { - "name": "js-event-loop-demo-server", + "name": "node-visualizer-server", "version": "1.0.0", "license": "MIT", "dependencies": { @@ -28,7 +28,7 @@ "jest-junit": "^12.0.0" }, "engines": { - "node": "11.x" + "node": ">=16.x" } }, "node_modules/@babel/code-frame": { @@ -2337,7 +2337,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==", - "deprecated": "core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3." + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." }, "node_modules/core-util-is": { "version": "1.0.2", @@ -4509,6 +4509,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" @@ -6912,6 +6913,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" @@ -7030,6 +7032,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", "dev": true, "dependencies": { "@cnakazawa/watch": "^1.0.3", @@ -7614,6 +7617,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, "dependencies": { "atob": "^2.1.2", @@ -7635,6 +7639,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", "dev": true }, "node_modules/spdx-correct": { diff --git a/package.json b/package.json index 8e805a6..36a00e8 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,10 @@ "main": "index.js", "license": "MIT", "engines": { - "node": "11.x" + "node": ">=16.x" }, "scripts": { - "start": "node --experimental-worker index.js", + "start": "node index.js", "test": "jest" }, "dependencies": { diff --git a/src/main/eventsReducer.js b/src/main/eventsReducer.js index 6ceb78d..2dda0a3 100644 --- a/src/main/eventsReducer.js +++ b/src/main/eventsReducer.js @@ -198,12 +198,15 @@ const reduceEvents = (events) => { }) ); - // console.log({ - // resolvedPromiseIds, - // promisesWithInvokedCallbacksInfo, - // parentsIdsOfPromisesWithInvokedCallbacks, - // parentsIdsOfMicrotasks, - // }); + console.log({ + resolvedPromiseIds, + promisesWithInvokedCallbacksInfo, + parentsIdsOfPromisesWithInvokedCallbacks, + promiseChildIdToParentId, + microtasksWithInvokedCallbacksInfo, + microtaskChildIdToParentId, + parentsIdsOfMicrotasks, + }); return events.reduce(eventsReducer, { events: [], diff --git a/src/worker/asyncHook.js b/src/worker/asyncHook.js index 6a6730b..c5e5b66 100644 --- a/src/worker/asyncHook.js +++ b/src/worker/asyncHook.js @@ -6,6 +6,7 @@ function debug(...args) { } const asyncIdToResource = {}; const init = (asyncId, type, triggerAsyncId, resource) => { + debug(`asyncId:${asyncId}, type:${type}, taid:${triggerAsyncId}, resource:`,resource); asyncIdToResource[asyncId] = resource; if (type === 'PROMISE') { postEvent(Events.InitPromise(asyncId, triggerAsyncId)); @@ -45,7 +46,7 @@ const init = (asyncId, type, triggerAsyncId, resource) => { const before = (asyncId) => { const resource = asyncIdToResource[asyncId] || {}; const resourceName = resource.constructor.name; - if (resourceName === 'PromiseWrap') { + if (resourceName === 'Promise') { postEvent(Events.BeforePromise(asyncId)); } if (resourceName === 'Timeout') { @@ -56,22 +57,22 @@ const before = (asyncId) => { const callbackName = resource._onImmediate.name || 'anonymous'; postEvent(Events.BeforeImmediate(asyncId, callbackName)); } - if ( - resourceName === 'Object' && - resource.callback && - resource.callback.name !== 'maybeReadMore_' && - resource.callback.name !== 'afterWriteTick' && - resource.callback.name !== 'onSocketNT' && - resource.callback.name !== 'initRead' && - resource.callback.name !== 'emitReadable_' && - resource.callback.name !== 'emitCloseNT' && - resource.callback.name !== 'endReadableNT' && - resource.callback.name !== 'finish' && - resource.callback.name !== 'resume_' - ) { - const callbackName = resource.callback.name || 'anonymous'; - postEvent(Events.BeforeMicrotask(asyncId, callbackName)); - } + // if ( + // resourceName === 'Object' && + // resource.callback && + // resource.callback.name !== 'maybeReadMore_' && + // resource.callback.name !== 'afterWriteTick' && + // resource.callback.name !== 'onSocketNT' && + // resource.callback.name !== 'initRead' && + // resource.callback.name !== 'emitReadable_' && + // resource.callback.name !== 'emitCloseNT' && + // resource.callback.name !== 'endReadableNT' && + // resource.callback.name !== 'finish' && + // resource.callback.name !== 'resume_' + // ) { + // const callbackName = resource.callback.name || 'anonymous'; + // postEvent(Events.BeforeMicrotask(asyncId, callbackName)); + // } // if (resourceName === 'AsyncResource') { // postEvent(Events.BeforeMicrotask(asyncId)); // } @@ -80,7 +81,7 @@ const before = (asyncId) => { const after = (asyncId) => { const resource = asyncIdToResource[asyncId] || {}; const resourceName = resource.constructor.name; - if (resourceName === 'PromiseWrap') { + if (resourceName === 'Promise') { postEvent(Events.AfterPromise(asyncId)); } // if (resourceName === 'AsyncResource') { From 08538045386eca52fd55e5a3919731e1242a6f79 Mon Sep 17 00:00:00 2001 From: Gabriel Trujillo Date: Mon, 10 Oct 2022 21:05:56 -0500 Subject: [PATCH 2/2] Added basic support for queueMicrotask --- .gitignore | 3 ++- .vscode/launch.json | 20 -------------------- src/main/eventsReducer.js | 6 ++++-- src/worker/asyncHook.js | 24 ++++++++++++------------ 4 files changed, 18 insertions(+), 35 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.gitignore b/.gitignore index 893239e..1294e7a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ log.txt node_modules log-app.txt coverage -junit.xml \ No newline at end of file +junit.xml +.vscode/launch.json \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 5b5b95b..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - { - "type": "node", - "request": "launch", - "name": "Launch Program", - "skipFiles": [ - "/**" - ], - "runtimeExecutable": "/Users/gabbytee/.nvm/versions/node/v16.17.1/bin/node", - "cwd":"${workspaceFolder}/Node-EventLoop-Visualizer-Server/", - "program": "${workspaceFolder}/Node-EventLoop-Visualizer-Server/index.js" - } - ] -} \ No newline at end of file diff --git a/src/main/eventsReducer.js b/src/main/eventsReducer.js index 2dda0a3..2da3a12 100644 --- a/src/main/eventsReducer.js +++ b/src/main/eventsReducer.js @@ -57,10 +57,12 @@ const eventsReducer = (state, evt) => { ({ asyncID }) => asyncID === payload.asyncID ); - if (microtaskInfo) { + if ( + (microtaskInfo) || + (state.prevEvt.type==='EnterFunction' && state.prevEvt.payload.name==='queueMicrotask')) { state.events.push({ type: 'EnqueueMicrotask', - payload: { name: microtaskInfo.name }, + payload: { name: microtaskInfo?.name || 'microtask' }, // TODO: Get callback name for q'd µtasks }); } } diff --git a/src/worker/asyncHook.js b/src/worker/asyncHook.js index c5e5b66..1743d71 100644 --- a/src/worker/asyncHook.js +++ b/src/worker/asyncHook.js @@ -20,11 +20,11 @@ const init = (asyncId, type, triggerAsyncId, resource) => { const callbackName = resource._onImmediate.name || 'anonymous'; postEvent(Events.InitImmediate(asyncId, callbackName)); } - // if (type === 'Microtask') { - // const callbackName = resource.callback.name || 'anonymous'; - // debug(resource); - // postEvent(Events.InitMicrotask(asyncId, triggerAsyncId, callbackName)); - // } + if (type === 'Microtask') { + const callbackName = resource.callback?.name || 'anonymous'; + debug('Microtask: ', resource); + postEvent(Events.InitMicrotask(asyncId, triggerAsyncId, callbackName)); + } if ( type === 'TickObject' && resource.callback.name !== 'maybeReadMore_' && @@ -37,7 +37,7 @@ const init = (asyncId, type, triggerAsyncId, resource) => { resource.callback.name !== 'finish' && resource.callback.name !== 'resume_' ) { - const callbackName = resource.callback.name || 'anonymous'; + const callbackName = resource?.callback?.name || 'microtask'; debug(callbackName); postEvent(Events.InitMicrotask(asyncId, triggerAsyncId, callbackName)); } @@ -73,9 +73,9 @@ const before = (asyncId) => { // const callbackName = resource.callback.name || 'anonymous'; // postEvent(Events.BeforeMicrotask(asyncId, callbackName)); // } - // if (resourceName === 'AsyncResource') { - // postEvent(Events.BeforeMicrotask(asyncId)); - // } + if (resourceName === 'AsyncResource') { + postEvent(Events.BeforeMicrotask(asyncId)); + } }; const after = (asyncId) => { @@ -84,9 +84,9 @@ const after = (asyncId) => { if (resourceName === 'Promise') { postEvent(Events.AfterPromise(asyncId)); } - // if (resourceName === 'AsyncResource') { - // postEvent(Events.AfterMicrotask(asyncId)); - // } + if (resourceName === 'AsyncResource') { + postEvent(Events.AfterMicrotask(asyncId)); + } }; const destroy = (asyncId) => {