Try the whole ladder, rather than five eighths of it

MAX_ATTEMPTS was 5 while CANDIDATES was 8, so three ranked candidates were
gathered and then never tried. The cap was arbitrary and the live numbers show
what it cost.

slskd answers 500 whenever it cannot open a connection to a peer, and that is
common: retrying "Michael Jackson - Billie Jean" walked four unreachable peers
before the fifth served it -- succeeding on precisely the last attempt the cap
allowed. "The Weeknd - Die For You" ran the same gauntlet and lost, giving up
with three untried candidates still on the row.

Defaults to CANDIDATES, so the ladder is the ladder. Anyone wanting the old
behaviour can still set MUSE_MAX_ATTEMPTS.

The cap test lowers the value explicitly now; with the two equal by default it
was only ever proving the list ran out, which is the other branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Aryan SinghandClaude Opus 5 committed 2026-09-02 11:59:52 -05:00
1 parent baa936e88d
commit 0ebc9515b4
3 files changed
+16 -3

No files matched your search

+7 -1
View File
@@ -209,12 +209,18 @@ def main() -> int:
# every peer refuses to accept the transfer
fake2.enqueue_status = {f"u{i}": 500 for i in range(8)}
app.slskd_client = fake2
# The cap defaults to the ladder size, so lower it here or this only ever
# proves the list ran out -- which is a different branch.
cap, app.MAX_ATTEMPTS = app.MAX_ATTEMPTS, 3
make_job("j2", "Radiohead", "Creep")
asyncio.run(app.pick_and_enqueue("j2", "Radiohead", "Creep"))
r = job_row("j2")
check("gives up at MAX_ATTEMPTS, not at the end of the list",
r["state"] == "failed" and r["attempts"] == app.MAX_ATTEMPTS,
r["state"] == "failed" and r["attempts"] == 3,
f"state={r['state']} attempts={r['attempts']}")
check("and leaves the untried remainder alone",
len(json.loads(r["candidates"] or "[]")) > 0, r["candidates"])
app.MAX_ATTEMPTS = cap
check("unreachable peers are reported as such",
"could not reach peer" in (r["tried"] or ""), r["detail"])