1tube 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "1tube",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "private": false,
5
5
  "description": "Self-hosted Supabase Edge Functions gateway for Deno, plus an ESLint plugin for consumers",
6
6
  "license": "MIT",
@@ -1352,89 +1352,85 @@ export function createWorkerdBackend(opts: WorkerdBackendOptions): WorkerdBacken
1352
1352
 
1353
1353
  // Preflight: refuse to spawn workerd against ports that are
1354
1354
  // already in use. Without this, a leftover workerd from a
1355
- // previous run silently steals our traffic and the failure
1356
- // surfaces only as wrong-looking response bodies. See
1357
- // `probeSocketsFree` doc comment for the full rationale.
1358
- // We skip the check on reload because the still-serving old
1359
- // generation occupies the OTHER slot's ports by design — the
1360
- // even/odd `slot` shift above guarantees no overlap, and
1361
- // probing here would race against that intentional overlap.
1362
- if (args.gen === 0) {
1363
- let conflicts = probeSocketsFree(capnp.routes);
1364
- if (conflicts.length > 0 && opts.killStaleWorkerd) {
1365
- console.log(
1366
- `[1tube] port preflight found ${conflicts.length} conflict(s); ` +
1367
- `--kill-stale-workerd is set, attempting cleanup...`,
1368
- );
1355
+ // previous run can satisfy the readiness probe and silently
1356
+ // steal our traffic; the failure then surfaces only as stale
1357
+ // response bodies. On reload the still-serving current process
1358
+ // occupies the OTHER slot's ports by design, so probing the next
1359
+ // slot is safe and catches orphaned older generations.
1360
+ let conflicts = probeSocketsFree(capnp.routes);
1361
+ if (conflicts.length > 0 && opts.killStaleWorkerd) {
1362
+ console.log(
1363
+ `[1tube] port preflight found ${conflicts.length} conflict(s)` +
1364
+ (args.gen > 0 ? ` for reload gen=${args.gen}` : "") +
1365
+ `; --kill-stale-workerd is set, attempting cleanup...`,
1366
+ );
1369
1367
 
1370
- // First try the precise fix: resolve the conflicted port(s)
1371
- // to their owning PID(s), and kill only owners named workerd.
1372
- // That is the behavior we want during firmware flashing:
1373
- // remove the stale candidate that owns 8800, but never kill
1374
- // a random non-workerd process that happens to be there.
1375
- const targeted = await killWorkerdOwnersOfPorts(conflicts);
1376
- if (targeted.attempted) {
1377
- if (targeted.code === 0) {
1378
- const details = targeted.stdout?.trim();
1379
- console.log(
1380
- `[1tube] targeted stale-workerd cleanup by port complete` +
1381
- (details ? ` (${details})` : "") +
1382
- `; re-probing...`,
1383
- );
1384
- } else {
1385
- console.warn(
1386
- `[1tube] targeted stale-workerd cleanup exited ${targeted.code}` +
1387
- (targeted.stderr ? `: ${targeted.stderr.trim()}` : ""),
1388
- );
1389
- }
1390
- await new Promise((r) => setTimeout(r, 250));
1391
- conflicts = probeSocketsFree(capnp.routes);
1368
+ // First try the precise fix: resolve the conflicted port(s)
1369
+ // to their owning PID(s), and kill only owners named workerd.
1370
+ // That is the behavior we want during firmware flashing:
1371
+ // remove the stale candidate that owns 8800, but never kill
1372
+ // a random non-workerd process that happens to be there.
1373
+ const targeted = await killWorkerdOwnersOfPorts(conflicts);
1374
+ if (targeted.attempted) {
1375
+ if (targeted.code === 0) {
1376
+ const details = targeted.stdout?.trim();
1377
+ console.log(
1378
+ `[1tube] targeted stale-workerd cleanup by port complete` +
1379
+ (details ? ` (${details})` : "") +
1380
+ `; re-probing...`,
1381
+ );
1382
+ } else {
1383
+ console.warn(
1384
+ `[1tube] targeted stale-workerd cleanup exited ${targeted.code}` +
1385
+ (targeted.stderr ? `: ${targeted.stderr.trim()}` : ""),
1386
+ );
1392
1387
  }
1388
+ await new Promise((r) => setTimeout(r, 250));
1389
+ conflicts = probeSocketsFree(capnp.routes);
1390
+ }
1393
1391
 
1394
- // If targeted cleanup did not exist on this platform, or it
1395
- // found no matching workerd owner, fall back to the old typed
1396
- // process-name cleanup.
1397
- const result = conflicts.length > 0 ? await killStaleWorkerd() : null;
1398
- if (result === null) {
1399
- // Already clear.
1400
- } else
1401
- if (result.attempted) {
1402
- // taskkill returns 128 when no matching image is running —
1403
- // that's not an error in our context (means the offender
1404
- // wasn't workerd, which is fine; preflight will catch it).
1405
- // pkill returns 1 in the same case.
1406
- const noMatch = (Deno.build.os === "windows" && result.code === 128) ||
1407
- (Deno.build.os !== "windows" && result.code === 1);
1408
- if (result.code === 0) {
1409
- console.log(`[1tube] killed leftover workerd process(es); re-probing...`);
1410
- } else if (noMatch) {
1411
- console.log(
1412
- `[1tube] no leftover workerd processes found; the conflict is held ` +
1413
- `by something else (re-probing to confirm)...`,
1414
- );
1415
- } else {
1416
- console.warn(
1417
- `[1tube] ${result.command?.join(" ")} exited ${result.code}` +
1418
- (result.stderr ? `: ${result.stderr.trim()}` : ""),
1419
- );
1420
- }
1421
- // Brief settle time: Windows TCP sockets in CLOSE_WAIT can
1422
- // hold the port for a fraction of a second after the owner
1423
- // process is killed. 250ms is empirically enough on the
1424
- // dev boxes we've tested without making the boot path feel
1425
- // sluggish.
1426
- await new Promise((r) => setTimeout(r, 250));
1427
- conflicts = probeSocketsFree(capnp.routes);
1392
+ // If targeted cleanup did not exist on this platform, or it
1393
+ // found no matching workerd owner, fall back to the old typed
1394
+ // process-name cleanup.
1395
+ const result = conflicts.length > 0 ? await killStaleWorkerd() : null;
1396
+ if (result === null) {
1397
+ // Already clear.
1398
+ } else if (result.attempted) {
1399
+ // taskkill returns 128 when no matching image is running —
1400
+ // that's not an error in our context (means the offender
1401
+ // wasn't workerd, which is fine; preflight will catch it).
1402
+ // pkill returns 1 in the same case.
1403
+ const noMatch = (Deno.build.os === "windows" && result.code === 128) ||
1404
+ (Deno.build.os !== "windows" && result.code === 1);
1405
+ if (result.code === 0) {
1406
+ console.log(`[1tube] killed leftover workerd process(es); re-probing...`);
1407
+ } else if (noMatch) {
1408
+ console.log(
1409
+ `[1tube] no leftover workerd processes found; the conflict is held ` +
1410
+ `by something else (re-probing to confirm)...`,
1411
+ );
1428
1412
  } else {
1429
1413
  console.warn(
1430
- `[1tube] could not run ${result.command?.join(" ")}: ` +
1431
- `${result.stderr ?? "unknown error"}`,
1414
+ `[1tube] ${result.command?.join(" ")} exited ${result.code}` +
1415
+ (result.stderr ? `: ${result.stderr.trim()}` : ""),
1432
1416
  );
1433
1417
  }
1418
+ // Brief settle time: Windows TCP sockets in CLOSE_WAIT can
1419
+ // hold the port for a fraction of a second after the owner
1420
+ // process is killed. 250ms is empirically enough on the
1421
+ // dev boxes we've tested without making the boot path feel
1422
+ // sluggish.
1423
+ await new Promise((r) => setTimeout(r, 250));
1424
+ conflicts = probeSocketsFree(capnp.routes);
1425
+ } else {
1426
+ console.warn(
1427
+ `[1tube] could not run ${result.command?.join(" ")}: ` +
1428
+ `${result.stderr ?? "unknown error"}`,
1429
+ );
1434
1430
  }
1435
- if (conflicts.length > 0) {
1436
- throw new Error(formatPortConflictError(conflicts));
1437
- }
1431
+ }
1432
+ if (conflicts.length > 0) {
1433
+ throw new Error(formatPortConflictError(conflicts));
1438
1434
  }
1439
1435
 
1440
1436
  const inspectorArgs = buildInspectorExtraArgs(opts.inspectorAddr, slot);