tracker
All repositories: gitoria
2.6 KB
// tests/browser/ports.mjs — the two port questions the CDP driver has to ask,// and the reasons they are asked this way. They lived in the hl:web browser// tier's `fixtures.mjs` until that tier moved to `archive/hlweb-v1/`// (2026-09-10); the driver survives it, so its dependencies do too.//// Every process a caller starts is its own to kill BY PID — never `pkill -f`,// which on this machine matches sibling sessions' runners.//// `portOpen` (a plain connect) is NOT here: the driver keeps its own, because// "something answers" is a different question from "this port is free", and// only the second one needs the reasons written down.import { createServer as netServer } from 'node:net';import { execFileSync } from 'node:child_process';/*** A BIND IS THE QUESTION, SO A BIND IS THE TEST (mission 285). A listener on a* LAN address is invisible to a loopback connect and still takes the port from* a server that binds 0.0.0.0 — which is how a browser-tier red once looked* like a hung server: the app's own log said `bind() failed on port N` while* every "is it open?" probe said no.** Nothing is left behind: a listening socket with no accepted connections* leaves no TIME_WAIT when it closes.*/export function portBindable(port) {return bindProbe(port).then((r) => r.ok);}/*** The same probe with the kernel's own word for WHY. `EADDRINUSE` is a* collision and is what this file is about; anything else (EACCES, EMFILE …)* is a different problem and must not be reported as one, because an error* that names the wrong cause costs the next reader a whole night.*/function bindProbe(port) {return new Promise((res) => {const s = netServer();s.once('error', (e) => res({ ok: false, code: (e && e.code) || String(e) }));s.listen(port, '0.0.0.0', () => s.close(() => res({ ok: true, code: null })));});}/*** Every socket on `port`, in any state, with its owner — `ss -tanp`. LISTEN is* the state that actually blocks a bind (measured: TIME_WAIT and ESTABLISHED do* not, on loopback or on the LAN address), so a report showing only listeners* and finding none says "nothing", which is the least useful thing a diagnostic* can say. Show the whole port.*/export function whoHolds(port) {try {const out = execFileSync('ss', ['-tanp'], { encoding: 'utf-8' });const hits = out.split('\n').filter((l) => new RegExp(`:${port}(\\s|$)`).test(l));return hits.length? hits.map((l) => l.trim().replace(/\s+/g, ' ')).join('\n '): '(no socket on that port at all by the time `ss` ran — the holder let go between the failed bind and this line)';} catch { return '(`ss` is not runnable here)'; }}
Branches
- mainmain branch
Latest commits
- 31b758aatracker#10: installable app (manifest, service worker, offline shell), own icon + faviconmre
- 2fa9d997tracker#9: TMDB sync (followed shows: seasons, episodes, posters), tools/sync-tmdb.hl + daily run 04:00 UTC, fake TMDB in gatemre
- 49e1f61edeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- 54070a4etracker#8: /my/unwatched + /my/schedule (301 from old), S01E01, title (year), 1 episode, watched-set lookup (unwatched 15s -> 1s)mre
- 3251488atracker#7: /my/shows (followed shows, newest follow first, poster, title, last watched SxxEyy); gate can take screenshots (TRACKER_GATE_SHOTS)mre
- 44b7d9f9tracker#6: /schedule — upcoming episodes of followed shows, soonest firstmre
- 91c9fc8ctracker#5: /unwatched — unwatched released episodes of followed shows, newest firstmre
- a97c0295tracker#4: show page /shows/:slug (header, seasons, episodes, watch checks) + tools/relink-episode-seasons.hlmre
- 05f407c5tracker: no border on any button except inverted ones (Log out, ident status and identities too); header brand weight 100mre
- 17375427tracker#2: tools/migrate.hl + tools/verify.hl — old MongoDB data into mpackdb with new idsmre
- 31aac936tracker#3: no border on the header and on filled buttons; inverted buttons keep theirsmre
- 2ad9d29ctracker#1: login exactly like calendar (identity selector in the header, empty homepage)mre
- 3691e176tracker#1: empty tracker with the ident login (state of 2026-09-27)mre