Skip to content

Commit 28c4002

Browse files
committed
wip
1 parent cce8b07 commit 28c4002

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

src/cli.js

+30
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,36 @@ async function build() {
891891
}
892892
})
893893

894+
/**
895+
* When rapidly saving files atomically a couple of situations can happen:
896+
* - The file is missing since the external program has deleted it by the time we've gotten around to reading it from the earlier save.
897+
* - The file is being written to by the external program by the time we're going to read it and is thus treated as busy because a lock is held.
898+
*
899+
* To work around this we retry reading the file a handful of times with a delay between each attempt
900+
*
901+
* @param {string} path
902+
* @param {number} tries
903+
* @returns {string}
904+
* @throws {Error} If the file is still missing or busy after the specified number of tries
905+
*/
906+
async function readFileWithRetries(path, tries = 5) {
907+
for (let n = 0; n < tries; n++) {
908+
try {
909+
return await fs.promises.readFile(path, 'utf8')
910+
} catch (err) {
911+
if (n < tries) {
912+
if (err.code === 'ENOENT' || err.code === 'EBUSY') {
913+
await new Promise((resolve) => setTimeout(resolve, 10))
914+
915+
continue
916+
}
917+
}
918+
919+
throw err
920+
}
921+
}
922+
}
923+
894924
// Restore watching any files that are "removed"
895925
// This can happen when a file is pseudo-atomically replaced (a copy is created, overwritten, the old one is unlinked, and the new one is renamed)
896926
// TODO: An an optimization we should allow removal when the config changes

0 commit comments

Comments
 (0)