Repository navigation
Add eventual provider diversity with safe additive STRMs - #18
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 98630a8b4d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| else if (ep.Diversity.Status is "retired" or "resolved") | ||
| { ep.Diversity.Status = "waiting"; ep.Diversity.Reason = "single_source"; | ||
| ep.Diversity.NextAttempt = now.AddHours(6); } |
There was a problem hiding this comment.
Preserve the due time across routine refresh indexing
When a single-source item receives its normal hourly refresh, CompleteAsync temporarily changes its state to awaiting_indexing, so reconciliation retires the diversity entry; once Emby reports it indexed again, this branch resets NextAttempt to another six hours. Because ImportWorkBudget.NeedsRefresh makes the same item refreshable again after only one hour, small libraries that revisit items within six hours repeat this cycle indefinitely and never dispatch the new diversity lookup. Preserve the existing due time across this transient refresh/indexing state, or only restart the window when the saved provider set actually changes.
Useful? React with 👍 / 👎.
| if (work.Diversity) | ||
| { | ||
| var entry = episode.Diversity; | ||
| if (!_diversityEnabled() || entry == null || entry.Profile != _inventory.ProfileFingerprint || | ||
| entry.Generation != live.Generation || !ImportDiversityPolicy.Eligible(live, episode) || | ||
| DiversitySignature(episode) != work.Signature) | ||
| { | ||
| if (entry != null) { entry.Status = "waiting"; entry.Reason = "guard_changed"; entry.NextAttempt = now.AddMinutes(5); } | ||
| episode.Lease = null; episode.LeaseUntil = null; | ||
| await _db.SaveImportCoverageAsync(live, token); return; |
There was a problem hiding this comment.
Clear diversity leases before rejecting final guards
When a diversity lookup is in flight and Repair is switched to Observe, the coverage generation changes, or the item becomes blocked/owned/ineligible, the shared guard above returns before this diversity-specific cleanup executes. The persisted entry therefore remains in_flight with its lease until expiry instead of immediately becoming waiting or retired, hiding completed work and delaying any later recovery by the ten-minute lease plus reconciliation delay. Handle diversity guard rejection and lease cleanup before the shared early return.
Useful? React with 👍 / 👎.
Marvin now discovers one durable provider-diversity entry per indexed single-source movie or episode. After a six-hour wait, it spends only spare native credits on serial checks, applies escalating backoff, and adds one validated unfamiliar-provider STRM without replacing the working set. Existing repairs, blocks, ownership, cooldowns, deadlines and rolling safeguards remain authoritative.
The native admin can pause only diversity. Status and telemetry distinguish its reservations/publications from repair attempts. README and the detailed queue contract specify eligibility, schema, leases, priority, health predicates, every retry rung, interrupted work, capacity limits and rollback.
Validation: pinned Emby 4.10.0.40 container build, 263 passing tests, repository check; isolated native Emby QA confirmed normal admin controls/anonymous denial, same-source preservation, restart persistence, two additive publications, six saved hash/size-evidence checks and native episode indexing. Synthetic targets were used; playback is not claimed.
Fixes #17.