Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

TypeScript: single-instance lock for the listening socket

Aperta
#46 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
38/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
c, docker, node.js, typescript

Direzione di ricerca

Read the existing Go and Rust lock implementations, then inspect the TypeScript listener and ts/Dockerfile. Run the skipped openListener concurrent test in ts/src/listen.test.ts and review spec/listener.qnt plus the TypeScript exception in spec/listener-design.md. Done means the locked configuration and TypeScript lock tests pass, concurrency leaves exactly one server, and reproducibility remains bit-for-bit.

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

Descrizione

Type: Enhancement

Is your feature request related to a problem?

#45 adds a single-instance lock to Go and Rust: flock(LOCK_EX|LOCK_NB) on <listen-socket>.lock, held for as long as the process runs. Node has no flock. On Node 22, fs.flock is undefined, there is no fcntl locking, and O_EXLOCK doesn't exist on Linux. So TypeScript relies only on the "in use" check (it connect(2)s to the existing socket before deleting it). That leaves a race between checking and deleting:

  1. A connects: refused, so the socket is stale.
  2. B connects: refused, so the socket is stale.
  3. A deletes the socket and binds. A is now live.
  4. B deletes A's live socket and binds. A keeps running, but nothing can reach it.

This only happens when two TypeScript instances start within a few milliseconds of each other on the same path. A second instance that starts after the first is listening is still refused. The race is recorded formally as raceWithoutLockTest in spec/listener.qnt, using the listener_unlocked module. It is a documented exception to the equal-peers rule; see spec/listener-design.md, section "TypeScript exception".

Describe the solution

A small in-repo N-API addon, about 30 lines of C, exposing flock(fd, LOCK_EX|LOCK_NB), with no npm dependency. TypeScript then uses the same lock as Go and Rust: the same file path, mode, O_NOFOLLOW and error messages.

This needs a change to ts/Dockerfile, which currently runs npm ci --ignore-scripts on stagex/pallet-nodejs. Either allow install scripts for that one package, or build the addon in an explicit step on stagex/pallet-nodejs or a StageX C-toolchain stage. make verify-reproducible-ts must stay bit-for-bit reproducible.

Done when:

  • the listener_locked Quint configuration covers TypeScript as well;
  • the skipped test openListener concurrent in ts/src/listen.test.ts is un-skipped and passes (8 instances started together, repeated 50 times, and exactly one ends up serving);
  • TypeScript passes the same lock unit tests as Go and Rust (symlink refused, unreadable lock file, released on SIGKILL).

Describe alternatives

  • An fs-ext-style npm addon: rejected. It's an external dependency built by install scripts.
  • Calling flock(1) from a shell: rejected. util-linux isn't in the runtime image.
  • An abstract-namespace lock socket: rejected. It's Linux-only and scoped to a network namespace, so two containers sharing a socket volume wouldn't see each other's lock.
  • A lock-free link(2)/rename(2) replace-and-check-inode protocol: rejected. It can still orphan a socket when three instances start together, and a live socket briefly disappears while it's being put back.

Which implementation(s) would this affect?

  • Go
  • Rust
  • TypeScript
  • Quint specification
  • All

Additional context

Follow-up to #45.

Lingua principale
Rust
Stelle
2
Fork
0
Merge medio
13h 22m
PR unite (30g)
27

Preparare l'ambiente

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 ChainSafe/docker-socket-policy

Tutte le issue di ChainSafe/docker-socket-policy

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.