Windows flake: daemon-foreground-relaunch e2e cleanup hits ENOTEMPTY while the unawaited stop CLI still writes the state dir

Aperta Adatta ai principianti
#2,918 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
github-actions, javascript, node.js
Ambito
cli, testing

Direzione di ricerca

Inizia da test/core/daemon-foreground-relaunch.test.js intorno alla riga 282 e confronta i nuovi tentativi di pulizia in test/core/daemon.test.js e test/core/daemon-backfill-sweep-wiring.test.js. Mantieni il processo figlio di arresto di Windows e attendi che termini prima delle asserzioni del gateway e della pulizia, e assicurati che venga arrestato se la pulizia viene eseguita per prima. Il lavoro è completato quando il test passa ripetutamente su Windows e test-windows è verde.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Symptom

On test-windows, test/core/daemon-foreground-relaunch.test.js:282 ("an unsupervised daemon run applies a staged central config and keeps the gateway answering") sometimes fails after every assertion has passed. The cleanup fs.rm(root, { recursive: true, force: true }) in the finally block throws:

[Error: ENOTEMPTY: directory not empty, rmdir 'C:\Users\RUNNER~1\AppData\Local\Temp\hyp-t-2puvEe\hyp-relaunch-e2e-eWyA2J\.hyp\hypaware'] { errno: -4051, code: 'ENOTEMPTY', syscall: 'rmdir' }

There were three sightings on 2026-11-06. Each one passed when the failed job was re-run once:

PR Run Head Directory that would not empty
#2913 42136275812 715c1cbb .hyp\hypaware
#2914 42139698957 attempt 1 3ac79c02 .hyp\hypaware\dev-telemetry
#2916 42142432583 attempt 1 20dad66b .hyp\hypaware

None of these PRs touched the daemon or this test. Under the test-windows landing gate, every sighting costs a re-run before a PR can land.

Likely cause

On win32 the test stops the daemon through the LLP 0300 file control channel. It spawns hyp daemon stop and does not keep a handle on that process:

if (process.platform === 'win32') {
  spawn(process.execPath, [path.join(REPO_ROOT, 'bin', 'hypaware.js'), 'daemon', 'stop'], { env, stdio: 'ignore' })
}

The test then waits only for the daemon to exit before fs.rm runs. The stop CLI is a second process with the same HYP_HOME and HYP_DEV_TELEMETRY=1. requestDaemonStop (src/core/daemon/runtime.js) polls until the daemon's pid is gone. Only after that does the CLI:

  • reconcile the pid files under the state root;
  • print daemon: stopped;
  • flush its own dev telemetry into <HYP_HOME>/hypaware/dev-telemetry (src/core/observability/logger.js, meter.js, tracer.js);
  • exit. That work overlaps the recursive delete:
  • Windows rmdir fails with ENOTEMPTY when an entry is created while the delete is running;
  • it also fails when a file is still open by a live process.

The #2914 sighting failing on dev-telemetry itself supports this reading. POSIX never hits the race because it stops the daemon with proc.kill('SIGTERM') in-process.

Proposed fix (test-only, bounded)

  1. Keep the stop child and await its exit before the gateway assertions and the cleanup. If it is still alive when finally runs, kill it.
  2. Give the cleanup the bounded retry the sibling daemon tests already use: fs.rm(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }). Examples are test/core/daemon.test.js:956 and test/core/daemon-backfill-sweep-wiring.test.js:139. That bounds the wait at about 1s worst case. Step 2 alone would hide the race rather than close it, so step 1 is the fix and step 2 is the backstop.

No product code changes. The stop CLI tidying pid files and flushing its telemetry after the daemon exits is the correct order.

Validation

Windows is gated by LLP 0584 #validation, and test-windows is a landing gate. The fix is proven by a green test-windows on the fixing head, plus the test passing in a loop on a Windows runner. Linux and macOS are unaffected because they take the SIGTERM path.

Logs from the three runs are held in the HypForge review records for #2913, #2914 and #2916.

Lingua principale
JavaScript
Stelle
11
Fork
0
Merge medio
2h 15m
PR unite (30g)
322

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di hyparam/hypaware

Tutte le issue di hyparam/hypaware

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.