Phase 4: stall-driven failover and node-level swarm wiring #3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "phase4-discovery"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The last two Phase 4 boxes, proven over a real swarm: multi-peer failover per D1 and graceful degradation when a peer vanishes mid-stream.
Server-side failover (
7af3414). The playback server subscribes to the session reducer's own stall signal, exactly as the TODO-V1 Phase 4 note prescribed — no second, differently-tuned stall detector in the transport. One idle fire is pure honesty (the reducer marksstalled, metrics record it); consecutive fires with no bytes in between (failoverAfterStalls, default 2) make the server abandon the current source and re-request the remaining range from the transport, bounded bymaxFailovers(default 3). Every way a source can stop short of the promised span converges on that same bounded decision — including a new catch: a transport that ends without error but short of Content-Length can no longer be forwarded as a complete 200. Failover also covers a source that dies before its first byte (the strike count is deliberately independent of the reducer's state, because time-to-first-byte is exactly where a dead peer hurts most).Node wiring + transport hardening (
983ab50).attachSwarm(newsrc/runtime/bare/swarmnode.js) turns an openNode storage node into a peer: servePeers answers from the real catalog, replicateStore serves bytes, swarmTransport fetches what it lacks — one swarm, one Corestore, andnode.close()wrapped so the swarm always dies before storage. Critical fix found by the new tests:swarmTransport.stream's per-chunk deadline existed but its cleanup awaited the underlying iterator'sreturn()unboundedly — a hypercore read against a vanished source may never settle (measured), so the escape hatch hung on its own latch. Cleanup is now bounded, and a failed chunk drops the mirror so a restart re-resolves against the swarm instead of reusing the dead one.Failover acceptance, over a real swarm (
test/runtime/failover.test.js, loopback DHT + UDX):failed.Tests: 1312/1312 asserts, lint clean. TODO-V1's Phase 4 boxes are all ticked, with what is and is NOT proven stated plainly (DHT re-discovery of a brand-new peer after the only seeder dies is hyperswarm refresh behavior, not something these tests pin).
This PR was created by an AI agent (OpenHands) on behalf of the user.