fix: better handle concurrent builds - #3301
dsanders11 wants to merge 8 commits into
Conversation
49c5a3c to
dad0d06
Compare
Signed-off-by: David Sanders <dsanders11@ucsbalum.com>
Assisted-by: Claude Opus 4.6 Signed-off-by: David Sanders <dsanders11@ucsbalum.com>
Assisted-by: Claude Opus 4.6 Signed-off-by: David Sanders <dsanders11@ucsbalum.com>
Signed-off-by: David Sanders <dsanders11@ucsbalum.com>
Assisted-by: Claude Opus 4.6 Signed-off-by: David Sanders <dsanders11@ucsbalum.com>
dad0d06 to
d7a1e4a
Compare
| } | ||
| }, 0) | ||
|
|
||
| await copyDirectory(srcDir, destDir) |
There was a problem hiding this comment.
Would you mind adding a test that srcDir is unchanged?
There was a problem hiding this comment.
I've added a test that moveDirectory (renamed it to reflect the changed semantics) retains the contents from srcDir moved to destDir. Let me know if I misunderstood what you were asking for here and I can add more test coverage.
| const srcPath = path.join(src, entry.name) | ||
| const destPath = path.join(dest, entry.name) | ||
| try { | ||
| await fs.rename(srcPath, destPath) |
There was a problem hiding this comment.
This changes the semantics to moveDirectory instead of copyDirectory.
There was a problem hiding this comment.
Happy to rename it and the files. You're right that now it's move, outside of the edge case of cross-device on Windows, which falls back to a copy and move.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Reflects the change in functionality Assisted-by: Claude Opus 4.6
Assisted-by: Claude Opus 4.6
The parallel native-addon fixture builds during `yarn install` each run `node-gyp install` into the shared devdir when it is cold, and one fixture's compile can read a header while another install is rewriting it (nodejs/node-gyp#3301), e.g. `v8-isolate.h: unterminated #ifndef` on linux-arm. The pre-seed that avoids this was skipped on Linux because the containers ship a pre-warmed cache, but that cache is keyed by the Node version of the runner that built the image and the arm32v7 test image runs Node 22.15.0, so it is always cold there. Run the pre-seed everywhere; it is a no-op when the cache is warm.
The parallel native-addon fixture builds during `yarn install` each run `node-gyp install` into the shared devdir when it is cold, and one fixture's compile can read a header while another install is rewriting it (nodejs/node-gyp#3301), e.g. `v8-isolate.h: unterminated #ifndef` on linux-arm. The pre-seed that avoids this was skipped on Linux because the containers ship a pre-warmed cache, but that cache is keyed by the Node version of the runner that built the image and the arm32v7 test image runs Node 22.15.0, so it is always cold there. Run the pre-seed everywhere; it is a no-op when the cache is warm.
This comment was marked as spam.
This comment was marked as spam.
| await fs.rename(srcPath, destPath) | ||
| } catch (err) { | ||
| if (RACE_ERRORS.includes(err.code)) { | ||
| // Another parallel process already placed this entry — ignore |
There was a problem hiding this comment.
I don't think this is a really good idea. This could result in a folder where some of its sub-entries are stale (like on windows it's still been used resulting in EBUSY), but some are new.
A directory already at the destination is not proof the contents match.
Checklist
npm install && npm run lint && npm testpassesDescription of change
Fixes #3165, which unfortunately was not actually fixed by #3170. I'm not sure #3170 had any effect on the issue, as my original changes in #2846 which were extended to all platforms in #3710 were targeting a specific issue on Windows, and did not aim to fix (or know of) the issue in #3165.
The second commit on this branch adds a test which repros the issue being reported in #3165, namely that header files can be seen as partially written when multiple builds are happening concurrently. A failing test run before the other commits on this branch can be seen here.
The remainder of the commits refactor
copyDirectoryto fix the issue, fix another concurrent build issue I came across during testing, and adds more test coverage. This refactor also allows for droppingexponential-backoffas a dependency.