From 5aedf7ea8d2f6613e9190c400b29e2b1d859ee2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kh=E1=BA=A3i?= Date: Tue, 29 Oct 2024 18:15:00 +0700 Subject: [PATCH] fix(dlx): race condition (#8712) --- .changeset/fifty-beers-hear.md | 6 ++++++ exec/plugin-commands-script-runners/src/dlx.ts | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/fifty-beers-hear.md diff --git a/.changeset/fifty-beers-hear.md b/.changeset/fifty-beers-hear.md new file mode 100644 index 0000000000..6d874b5f70 --- /dev/null +++ b/.changeset/fifty-beers-hear.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-script-runners": patch +"pnpm": patch +--- + +Fix race condition of symlink creations caused by multiple parallel `dlx` processes. diff --git a/exec/plugin-commands-script-runners/src/dlx.ts b/exec/plugin-commands-script-runners/src/dlx.ts index 6ca8eff811..449139b396 100644 --- a/exec/plugin-commands-script-runners/src/dlx.ts +++ b/exec/plugin-commands-script-runners/src/dlx.ts @@ -95,10 +95,11 @@ export async function handler ( await symlinkDir(cachedDir, cacheLink, { overwrite: true }) } catch (error) { // EBUSY means that there is another dlx process running in parallel that has acquired the cache link first. + // Similarly, EEXIST means that another dlx process has created the cache link before this process. // The link created by the other process is just as up-to-date as the link the current process was attempting // to create. Therefore, instead of re-attempting to create the current link again, it is just as good to let // the other link stay. The current process should yield. - if (!util.types.isNativeError(error) || !('code' in error) || error.code !== 'EBUSY') { + if (!util.types.isNativeError(error) || !('code' in error) || (error.code !== 'EBUSY' && error.code !== 'EEXIST')) { throw error } }