fix(worker): rank Soulseek peers by estimated transfer time, not raw speed
Peer selection ranked (free-slot, advertised-speed, short-queue), ignoring file size. But Soulseek FLAC rips of one album vary ~2x in size (a 24-bit/bloated rip vs a standard CD rip) and Lyra scores them the SAME quality class (the slskd search exposes no bit-depth, so every FLAC is class 2). So a peer advertising high speed but serving 40MB/track files would out-rank a smaller standard rip that actually finishes sooner — then blow past the 60-min per-peer backstop, time out, fall through, and restart at 0% (Linkin Park "Hybrid Theory" looping for hours). Rank by estimated transfer time instead: album bytes ÷ advertised speed, after the free-slot check. Prefers whichever peer FINISHES first — fast peers and/or smaller standard-edition rips — with no quality loss (all class 2). Equal-size case still reduces to speed order, so existing ranking behaviour is preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -110,6 +110,21 @@ def test_parse_ranks_free_and_fast_peers_first():
|
||||
assert peers == ["fast", "slow", "queued"] # free+fast first; no-slot peer last despite speed
|
||||
|
||||
|
||||
def test_parse_prefers_shorter_transfer_over_raw_speed():
|
||||
# The Hybrid Theory case: a peer advertising higher speed but serving a ~2x-larger rip (24-bit
|
||||
# / bloated FLAC) should lose to a peer with lower speed but a smaller standard rip that
|
||||
# finishes sooner — both are the same quality class to Lyra, so faster-to-finish wins.
|
||||
responses = [
|
||||
{"username": "bloated", "hasFreeUploadSlot": True, "uploadSpeed": 20000, "queueLength": 0,
|
||||
"files": [{"filename": rf"x\LP - Album\{i:02}.flac", "size": 40_000_000} for i in range(12)]},
|
||||
{"username": "lean", "hasFreeUploadSlot": True, "uploadSpeed": 15000, "queueLength": 0,
|
||||
"files": [{"filename": rf"y\LP - Album\{i:02}.flac", "size": 24_000_000} for i in range(12)]},
|
||||
]
|
||||
# bloated est = 480MB/20000 = 24000s; lean est = 288MB/15000 = 19200s → lean finishes first
|
||||
peers = [json.loads(c["source_ref"])["username"] for c in _parse_search_responses(responses)]
|
||||
assert peers[0] == "lean"
|
||||
|
||||
|
||||
def test_eta_seconds_from_measured_rate():
|
||||
assert _eta_seconds(1000, 250, 250.0) == 3 # 750 bytes left / 250 B/s
|
||||
assert _eta_seconds(1000, 0, 100.0) == 10
|
||||
|
||||
Reference in New Issue
Block a user