Skip to content

Engine/peer pool - #2

Merged
Langegen merged 3 commits into
mainfrom
engine/peer-pool
Nov 1, 2026
Merged

Langegen merged 3 commits into
mainfrom
engine/peer-pool

Conversation

@Langegen

@Langegen Langegen commented Nov 1, 2026

Copy link
Copy Markdown
Owner

No description provided.

Langegen and others added 3 commits November 1, 2026 15:46
The pool held 128 addresses and discarded everything trackers and DHT
reported once full (166 addresses in one run); dialing was round-robin.
Now it holds 1024 with a hash index and dials by score: peers that
delivered (and how fast) first, untried next, failed last. A full pool
replaces its worst entries. Unlike TorrentShopNX's score, the source is
only a tie-break: ranking tracker entries above DHT ones even after they
failed re-dialed tracker junk (boxes that accept TCP but never handshake)
while live peers waited. Sessions per IP are capped at 2 only until one
of them handshakes, so a seedbox's several clients still all count.

The DHT bootstrap list had a typo (dht.transmission.com) and the wrong
port for dht.libtorrent.org (25401, not 6881); on networks where the
bittorrent/utorrent routers do not answer, DHT never started.

The debug panel (ZR) shows the pool: addresses ready to dial and how
many were dropped because it was full.

pctest: a player model (`play` mode: mpv's head/tail probe, 60 s
read-ahead, the backlog fed to the engine) reporting startup and
stalls, and a Windows build (devkitPro MSYS2 mingw64). compat/: winsock
takes SO_RCVTIMEO in milliseconds, not a timeval -- every UDP tracker
and DHT reply timed out after 2 ms on the PC build.

Measured on PC, alternating old/new builds (DHT fix vs DHT fix + pool),
120 s per run at 10 Mbit/s: total stall time 151 s -> 49 s over five
pairs, median startup 21.3 s -> 17.8 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ported from TorrentShopNX's engine and adapted to a streaming leecher.

Peer exchange (BEP 11), receive only. Sessions now advertise the
extension protocol and ut_pex; addresses a live peer sends us go into
the pool. They are the freshest addresses there are: on this test
network DHT finds nothing, and PEX brought 100-500 addresses per run.
We never send PEX: TorrentShopNX measured libtorrent seeds dropping a
leecher that does so right after connecting.

Peer turnover. With DIAL_STOP_LIVE sessions up, dialing stopped and a
slow or permanently choking peer held its slot forever. Every 30 s, if
the pool has someone to try, 4 extra sessions may be dialed; after 40 s
the slowest measured ones are closed again, only on a clear loss (under
half the best rate). A peer that keeps us choked for 45 s is replaced.
Seeds of a scarce swarm are never touched, and nothing rotates while
the player has a buffer (calm mode).

Hedging. A session owns one piece at a time, so the player waited on
whichever peer owned the piece it needed next. When that owner has the
whole piece on order and goes silent for 1 s (or is 2x slower than an
idle peer), the idle peer re-requests the missing tail -- at most a
quarter of the piece, 16 blocks -- and the first copy wins. Only while
the player is short of buffer.

Debug panel and pctest: PEX addresses, rotated sessions, hedged blocks
and the bytes that arrived unneeded. CLAUDE.md: how to measure the
engine on a PC.

Not ported: MSE (no sign of plaintext handshakes being cut) and uTP in
the netloop (Switch's select() does not report UDP readability, so it
would need its own thread).

Measured on PC, alternating builds, 120 s per run at 10 Mbit/s:
- PEX vs the previous commit, 4 pairs: stall time 218 s -> 111 s,
  live peers 3/11/6/3 -> 10/17/19/17.
- With turnover and hedging, on the weak swarm (2 pairs): startup
  21-22 s -> 13-17 s, stall time 3.3/6.1 s -> 1.4/0.5 s. A first hedge
  limit of 16 blocks duplicated whole 256 KB pieces (13% of traffic
  wasted); the quarter-piece cap brought it to 0.7-3.7 MB per run.
- Turnover rarely fired on this network (it needs ~15 live peers and a
  hungry player), so its effect is unmeasured here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MAX_SESS 24 dated from before the borealis patch that cut the initial
TCP buffers, when socket() ran out of the buffer pool at ~20 sockets.
With that patch the pool fits far more; the pool itself is unchanged
(growing it starved the hardware video decoder).

Measured on PC: the earliest startups of the session (9-17 s on the
weak swarm, 14.6 s on the large one) and up to 32 live peers in one
run, beyond the old cap.

Kept apart so it can be reverted alone: on the console, watch the debug
panel's "fail: N sock/local" (ENOBUFS) and the decoder ("software"
instead of a hwdec); if either shows up, lower MAX_SESS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Langegen
Langegen merged commit e3957fa into main Nov 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant