`FileSystem.Lock.aquire` ends in `UnexpectedError ENOENT` when the lock is released while it checks it
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- javascript, node.js
- Ambito
- operating-systems
Direzione di ricerca
Inizia individuando l’handler LockMetaCheck e i predicati di errore di FileSystem nel codice sorgente di compiler-node. Esegui la riproduzione collegata o i comandi gren make/node mentre churn.js rimuove ripetutamente .lock. Il lavoro è completato quando un lock che scompare brevemente viene ritentato e l’esecuzione non segnala più UnexpectedError ENOENT, terminando solo con gli esiti lock acquired o already locked.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Found against: gren 0.6.6, gren-lang/compiler-node 5.0.0, gren-lang/core 7.4.2, gren-lang/node 6.1.3, node 22
Reproduction: https://github.com/gilramir/gren-bug-reports/tree/main/2026-09-16-lock-vanishes-during-metadata
Taking a lock that another process holds only briefly often ends in
UnexpectedError, when it should end with the lock taken or AlreadyLocked.
aquire creates the lock directory; if it exists, it reads its metadata to see
whether the lock is stale. If the other process removes the lock in between,
metadata fails with ENOENT, and the handler that means to retry tests for
the wrong error.
Reproduction
gren.json: a node application with "gren-lang/compiler-node": "5.0.0", "gren-lang/core": "7.4.2", "gren-lang/node": "6.1.3" (indirect "gren-lang/compiler-common": "3.0.0", "gren-lang/url": "6.0.0").
churn.js stands in for another process that holds the lock very briefly:
// Create and remove ./.lock in a tight loop, as another process holding the
// lock very briefly would.
const fs = require("node:fs");
for (;;) {
try { fs.mkdirSync(".lock"); } catch (e) {}
try { fs.rmdirSync(".lock"); } catch (e) {}
}
src/Main.gren tries to take the lock 2000 times, without retries, releasing it
whenever it gets it, and counts how each attempt ended:
(source elided here as it's very long)
gren make Main --output=app
node churn.js &
node app
Output (counts vary with timing):
outcome count
UnexpectedError ENOENT 953
already locked 156
lock acquired 891
Cause
LockMetaCheck { path, attempt, result = Err fsErr } ->
if FileSystem.errorIsFileExists fsErr then
-- Lock might have been removed while we asked for metadata
update fsPerm (Lock { path = fromLockPath path, attempt = attempt + 1 }) model
else
UnexpectedError { path = fromLockPath path, error = fsErr }
The comment describes the right recovery, but reading a directory's metadata
never fails with EEXIST, so a lock that has been removed takes the else
branch.
Proposed Fix
The check should be FileSystem.errorIsNoSuchFileOrDirectory
With it, the same program gave 325 already locked and 1675 lock acquired.
- Lingua principale
- JavaScript
- Stelle
- 2
- Fork
- 3
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Non abbiamo ancora controllato i file di configurazione di questo progetto. Parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di gren-lang/compiler-node
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
gren-lang/compiler-node#15 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
Tutte le issue di gren-lang/compiler-node
Issue simili
-
agent/quality hive/hosted-available-lke648397-260827-5n31 quality testing
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 Mezza giornata Idoneità per principianti 78/100
jaegertracing/jaeger-ui#4512 ·
I maintainer di solito rispondono entro 1 giorno
-
feedback simulation workshop
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
githubnext/gh-aw-workshop#3857 ·
I maintainer di solito rispondono entro 2 giorni
-
area-clientside-dartpad
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
quarkusio/extensions#3432 ·
I maintainer di solito rispondono entro 1 giorno