From 5f5b647ec4092e87266560f4aa0755e140e5d117 Mon Sep 17 00:00:00 2001 From: AgentEnder Date: Wed, 28 Feb 2024 15:27:44 -0500 Subject: [PATCH] fix(core): plugins should not be registered twice and should respect shutdown queue --- .../src/project-graph/plugins/internal-api.ts | 10 ++-- .../src/project-graph/plugins/plugin-pool.ts | 57 ++++++++++--------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/packages/nx/src/project-graph/plugins/internal-api.ts b/packages/nx/src/project-graph/plugins/internal-api.ts index de55fa15672917..8cb558638b91ff 100644 --- a/packages/nx/src/project-graph/plugins/internal-api.ts +++ b/packages/nx/src/project-graph/plugins/internal-api.ts @@ -44,7 +44,7 @@ export type RemotePlugin = // holding resolved nx plugin objects. // Allows loaded plugins to not be reloaded when // referenced multiple times. -export const nxPluginCache: Map = new Map(); +export const nxPluginCache: Map> = new Map(); export async function loadNxPlugins( plugins: PluginConfiguration[], @@ -78,12 +78,12 @@ export async function loadNxPlugin( const cacheKey = JSON.stringify(plugin); if (nxPluginCache.has(cacheKey)) { - return nxPluginCache.get(cacheKey)!; + return await nxPluginCache.get(cacheKey)!; } - const loadedPlugin = await loadRemoteNxPlugin(plugin, root); - nxPluginCache.set(cacheKey, loadedPlugin); - return loadedPlugin; + const loadingPlugin = loadRemoteNxPlugin(plugin, root); + nxPluginCache.set(cacheKey, loadingPlugin); + return await loadingPlugin; } export async function getDefaultPlugins(root: string) { diff --git a/packages/nx/src/project-graph/plugins/plugin-pool.ts b/packages/nx/src/project-graph/plugins/plugin-pool.ts index 340bce5a02f9b9..47aa9b00086c56 100644 --- a/packages/nx/src/project-graph/plugins/plugin-pool.ts +++ b/packages/nx/src/project-graph/plugins/plugin-pool.ts @@ -121,61 +121,42 @@ function createWorkerHandler( ? [ createNodesPattern, (configFiles, ctx) => { - return new Promise(function (res, rej) { - const tx = - pluginName + ':createNodes:' + performance.now(); + const tx = pluginName + ':createNodes:' + performance.now(); + return registerPendingPromise(tx, pending, () => { worker.send( createMessage({ type: 'createNodes', payload: { configFiles, context: ctx, tx }, }) ); - pending.add(tx); - promiseBank.set(tx, { - promise: this, - resolver: res, - rejecter: rej, - }); }); }, ] : undefined, createDependencies: result.hasCreateDependencies ? (opts, ctx) => { - return new Promise(function (res, rej) { - const tx = pluginName + ':createNodes:' + performance.now(); + const tx = pluginName + ':createNodes:' + performance.now(); + return registerPendingPromise(tx, pending, () => { worker.send( createMessage({ type: 'createDependencies', payload: { context: ctx, tx }, }) ); - pending.add(tx); - promiseBank.set(tx, { - promise: this, - resolver: res, - rejecter: rej, - }); }); } : undefined, processProjectGraph: result.hasProcessProjectGraph ? (graph, ctx) => { - return new Promise(function (res, rej) { - const tx = - pluginName + ':processProjectGraph:' + performance.now(); + const tx = + pluginName + ':processProjectGraph:' + performance.now(); + return registerPendingPromise(tx, pending, () => { worker.send( createMessage({ type: 'processProjectGraph', payload: { graph, ctx, tx }, }) ); - pending.add(tx); - promiseBank.set(tx, { - promise: this, - resolver: res, - rejecter: rej, - }); }); } : undefined, @@ -255,3 +236,27 @@ function getPendingPromises( } return pendingTxs; } + +function registerPendingPromise( + tx: string, + pending: Set, + callback: () => void +): Promise { + let resolver, rejecter; + const promise = new Promise((res, rej) => { + resolver = res; + rejecter = rej; + + callback(); + }); + pending.add(tx); + promiseBank.set(tx, { + promise: promise.then((val) => { + pending.delete(tx); + return val; + }), + resolver, + rejecter, + }); + return promise; +}