-
Notifications
You must be signed in to change notification settings - Fork 108
Description
Hello,
we use a monorepo and depend on multiple electron versions (some are the same and some are different). Lately we got hit by a race condition during yarn install
on Windows. The error message is:
yarn install v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
error D:\Git\electron-get-reproducer\modules\thirteen-a\node_modules\electron, D:\Git\electron-get-reproducer\modules\thirteen-b\node_modules\electron, D:\Git\electron-get-reproducer\modules\thirteen-c\node_modules\electron: Command failed.
Exit code: 1
Command: node install.js
Arguments:
Directory: D:\Git\electron-get-reproducer\modules\thirteen-b\node_modules\electron
Output:
Error: EPERM: operation not permitted, stat 'C:\Users\gregor.jasny\AppData\Local\electron\Cache\d8ba69554bfba792e726dc46341ce3ce2a2d8e7d4c50e66751fef4243f3087cd\electron-v13.3.0-win32-ia32.zip'
I went down the rabbit hole and created a reproducer for the behaviour. The working assumption was that due to hoisting we ended up with the same electron version in multiple locations of the workspace tree. Those then postinstall in parallel which causes issues.
With that reproducer I triggered the error after a few cycles of:
rmdir /S /Q "%LOCALAPPDATA%\electron\Cache"
git clean -fxd
yarn install
A parallel capture of all syscalls with procmon showed that:
- all three node processes first checked for a cached version of electron 13
- all three downloaded electron into a temporary file
- one finished first and moved the temporary file to the destination (move with overwrite)
- The two remaining processes wanted to open the destination file and got a "DELETE PENDING" syscall response
Would you be able to implement locking within @electron/get
to avoid the race condition and also avoid downloading electron multiple times? Or just add a retry loop?
Also yarn isn't innocent here. IMHO it should not trigger postinstall scripts for the same version of a package concurrently to avoid this type of issue. But damage is done and maybe @electron/get
could be made a little bit smarter to deal with the parallel invocvations.
Thanks,
Gregor