fix(downloads): stop searching a list there is nothing to search with #81

Closed
logan wants to merge 0 commits from fix/wanted-without-client into main
Collaborator

Closes #37.

Backend. Reconciler.run skipped nothing when no provider was enabled: every request was attempted, each failed with "no download clients are enabled", and RecordAttempt recorded that as an attempt and scheduled a retry. So a wanted list built deliberately without a client accrued failures and announced "next check in 6 hours" about a check that cannot happen.

The attempt phase is now gated on NoProviders. Everything above it still runs — an artist subscription still expands, and a request satisfied by another route (ripped, bought, copied in) is still retired; neither needs a provider.

Frontend. requestDetail takes canDownload and says "On your list — no download client to search with" instead of "Queued" or a retry time. Both were promises nothing was in a position to keep.

Tests.

  • TestNoProvidersMeansNoAttempt — nothing attempted, no attempt recorded, no lastError, and no retry pushed into the future (a fresh request is legitimately due now, so the assertion is about a time on the clock, not the presence of one). Fails four ways on main.
  • downloads-no-client.test.ts — the row does not mention a next check, and does again once a client exists.
  • TestReconcileRespectsBatchSize now installs a client that finds nothing: a batch size is how many requests one pass searches for, which only means something when there is something to search with.
Closes #37. **Backend.** `Reconciler.run` skipped nothing when no provider was enabled: every request was attempted, each failed with "no download clients are enabled", and `RecordAttempt` recorded that as an attempt *and scheduled a retry*. So a wanted list built deliberately without a client accrued failures and announced "next check in 6 hours" about a check that cannot happen. The attempt phase is now gated on `NoProviders`. Everything above it still runs — an artist subscription still expands, and a request satisfied by another route (ripped, bought, copied in) is still retired; neither needs a provider. **Frontend.** `requestDetail` takes `canDownload` and says "On your list — no download client to search with" instead of "Queued" or a retry time. Both were promises nothing was in a position to keep. **Tests.** - `TestNoProvidersMeansNoAttempt` — nothing attempted, no attempt recorded, no `lastError`, and no retry pushed into the future (a *fresh* request is legitimately due now, so the assertion is about a time on the clock, not the presence of one). Fails four ways on `main`. - `downloads-no-client.test.ts` — the row does not mention a next check, and does again once a client exists. - `TestReconcileRespectsBatchSize` now installs a client that finds nothing: a batch size is how many requests one pass *searches for*, which only means something when there is something to search with.
logan added 1 commit 2026-08-18 15:29:15 +00:00
fix(downloads): stop searching a list there is nothing to search with
CI / check (push) Skipped
CI / e2e (push) Skipped
CI / check (pull_request) Successful in 2m35s
CI / e2e (pull_request) Canceled after 0s
760021ea5a
Every pass attempted every request, each came back "no download clients
are enabled", and RecordAttempt wrote that down as an attempt and put a
retry on the clock -- so a wanted list built deliberately without a
client accrued failures and announced "next check in 6 hours" about a
check that cannot happen.

Wanting something with no way to fetch it is supported. Being told it
is being looked for is a lie, and the row says what is true instead.

Everything above the attempt still runs: an artist subscription still
expands, and a request satisfied by some other route -- ripped, bought,
copied in -- is still retired. Neither needs a provider.

TestReconcileRespectsBatchSize now installs a client that finds
nothing, because a batch size is about how many requests one pass
searches for and that only means something when there is something to
search with.

Refs #37
Author
Collaborator

Rolled into #83 and closed here — the commit is preserved as a merge on that branch, so it lands with its authorship and this PR's diff intact.

Batched deliberately: release.yml cuts a release on every push to main, so merging these one at a time would produce seven or eight releases for one afternoon of small fixes. #83 is one push and therefore one version.

The full gate was run against the combined tree rather than per branch: make lint (3 configs), make test (3 configs, -race), make ui-test (836), make e2e chromium (114), plus bindings/skill/commit checks.

Rolled into #83 and closed here — the commit is preserved as a merge on that branch, so it lands with its authorship and this PR's diff intact. Batched deliberately: `release.yml` cuts a release on **every** push to `main`, so merging these one at a time would produce seven or eight releases for one afternoon of small fixes. #83 is one push and therefore one version. The full gate was run against the combined tree rather than per branch: `make lint` (3 configs), `make test` (3 configs, `-race`), `make ui-test` (836), `make e2e` chromium (114), plus bindings/skill/commit checks.
logan closed this pull request 2026-08-18 15:44:25 +00:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.