Skip to content

fix(cache): revalidate cached torrent titles - #630

Open
wiktorekdev wants to merge 5 commits into
g0ldyy:mainfrom
wiktorekdev:fix/revalidate-cached-titles
Open

fix(cache): revalidate cached torrent titles#630
wiktorekdev wants to merge 5 commits into
g0ldyy:mainfrom
wiktorekdev:fix/revalidate-cached-titles

Conversation

@wiktorekdev

@wiktorekdev wiktorekdev commented Aug 12, 2026

Copy link
Copy Markdown

What changed

Cached torrent rows are now revalidated before they are returned:

  • the raw cached release title is parsed with the same parser/cache used by live filtering;
  • TitleMatcher checks the parsed title and release year against the requested media;
  • persisted parsed_json is not trusted as the authority for title matching;
  • invalid, empty, or mismatched cached titles are skipped;
  • primary_cached is set only after an accepted row from the primary media ID, including when duplicate info hashes are deduplicated across cache IDs.

Why

CometNet validates that an IMDb ID exists, but a propagated torrent's title can still be inconsistent with that ID. Because cached rows bypassed live title filtering, a release such as Into the Spider-Verse could be stored under Spider-Man: Homecoming and continue appearing in results.

Tests

  • uv run pytest tests/test_cached_title_revalidation.py tests/test_orchestration.py tests/test_filtering.py — 19 passed
  • uvx ruff check comet/services/filtering.py comet/services/orchestration.py tests/test_cached_title_revalidation.py tests/test_orchestration.py — passed
  • uv run python -m compileall -q comet — passed

The full suite cannot be collected on this Windows environment because mediaflow_proxy imports the Unix-only fcntl module in four existing streaming test modules.

Summary by CodeRabbit

  • Bug Fixes

    • Improved cached torrent matching to reject results with mismatched titles, years, media types, or aliases.
    • Prevented duplicate results from being incorrectly treated as primary-cache matches.
    • Corrected primary-cache status so it is set only for valid results associated with the primary media item.
    • Excluded invalid or unparsable cached results while preserving compatibility with older cached metadata.
  • Tests

    • Added coverage for matching titles, rejected mismatches, inconsistent metadata, and duplicate cache entries.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b6b1ecf-c3be-41fa-932b-daa5365f1f64

📥 Commits

Reviewing files that changed from the base of the PR and between 8b4d1e8 and 9d8ab36.

📒 Files selected for processing (1)
  • tests/test_cached_title_revalidation.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_cached_title_revalidation.py

Walkthrough

Cached torrent loading revalidates titles against requested metadata before insertion. Primary-cache status is set only for accepted matching torrents. The parse-cache helper is now named parse_with_cache. Tests cover rejection, legacy data, duplicate handling, and acceptance paths.

Changes

Cached Torrent Validation

Layer / File(s) Summary
Expose cached title parsing
comet/services/filtering.py
Renames _parse_with_cache to parse_with_cache and updates both call sites.
Revalidate cached rows and track primary status
comet/services/orchestration.py
Preserves source media IDs, deduplicates rows by info hash, and validates cached titles against the requested title, year range, media type, and aliases before insertion. Primary-cache state is assigned only to accepted rows from the primary media ID.
Validate cached-title behavior
tests/test_cached_title_revalidation.py, tests/test_orchestration.py
Tests mismatched and inconsistent data, legacy parsed data, matching rows, secondary duplicates, and the updated valid-title fixture.

Sequence Diagram(s)

sequenceDiagram
  participant Cache
  participant TorrentManager
  participant TitleMatcher
  Cache->>TorrentManager: provide cached torrent rows
  TorrentManager->>TitleMatcher: validate cached titles and metadata
  TitleMatcher-->>TorrentManager: accept or reject rows
  TorrentManager-->>Cache: store accepted rows and primary-cache state
Loading

Possibly related PRs

  • g0ldyy/comet#459: Both PRs modify cached torrent loading and title validation.
  • g0ldyy/comet#616: Both PRs modify cached-row handling in comet/services/orchestration.py.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: revalidation of cached torrent titles.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@comet/services/orchestration.py`:
- Around line 199-208: Preserve each row’s originating cache media ID through
the deduplication performed by best_rows, rather than deriving primary_cached
from all primary-cache info_hashes. Update the acceptance logic around
primary_cached to set it only when the selected row originated from
self.media_only_id, including the duplicate-hash case where a valid secondary
row replaces an invalid primary row. Add a regression test covering that
scenario.
- Around line 258-261: Update the cached-row filtering condition around
parsed_data.parsed_title to reject rows when no parsed title is present, while
retaining the existing TitleMatcher.matches validation for populated titles.
Align this behavior with filter_worker.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd33ec79-4088-4baa-9f36-1bb85c338f14

📥 Commits

Reviewing files that changed from the base of the PR and between f56677f and acfac13.

📒 Files selected for processing (2)
  • comet/services/orchestration.py
  • tests/test_cached_title_revalidation.py

Comment thread comet/services/orchestration.py Outdated
Comment thread comet/services/orchestration.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/test_cached_title_revalidation.py (1)

135-136: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert that the secondary row was retained.

The primary row is intentionally mismatched, so primary_cached == False is expected. assertIn does not prove that the accepted row came from secondary. Assert the retained row metadata against secondary. Add a valid/valid duplicate case if this test must directly cover source preservation.

Proposed assertion
         self.assertIn(duplicate_hash, manager.torrents)
+        self.assertEqual(
+            manager.torrents[duplicate_hash]["updatedAt"],
+            secondary["updated_at"],
+        )
         self.assertFalse(manager.primary_cached)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_cached_title_revalidation.py` around lines 135 - 136, Strengthen
the assertions in the cached-title revalidation test by verifying that
manager.torrents[duplicate_hash] retains the metadata from secondary, not merely
that the hash exists. Keep the expected primary_cached == False assertion, and
add a valid/valid duplicate case only if needed to directly verify
secondary-source preservation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/test_cached_title_revalidation.py`:
- Around line 135-136: Strengthen the assertions in the cached-title
revalidation test by verifying that manager.torrents[duplicate_hash] retains the
metadata from secondary, not merely that the hash exists. Keep the expected
primary_cached == False assertion, and add a valid/valid duplicate case only if
needed to directly verify secondary-source preservation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 484a8216-4061-49f2-866e-69e34eadf5c6

📥 Commits

Reviewing files that changed from the base of the PR and between ba13689 and 8b4d1e8.

📒 Files selected for processing (2)
  • comet/services/orchestration.py
  • tests/test_cached_title_revalidation.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • comet/services/orchestration.py

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