Skip to content

Fix Issue cache over- and under-invalidation - #605

Merged
bpepple merged 1 commit into
masterfrom
cache-bug-fix
Aug 20, 2026
Merged

Fix Issue cache over- and under-invalidation#605
bpepple merged 1 commit into
masterfrom
cache-bug-fix

Conversation

@bpepple

@bpepple bpepple commented Aug 20, 2026

Copy link
Copy Markdown
Member

Description

Production testing of the X-Cache header from #604 turned up an isolated HITMISS flip on an issue that hadn't been edited. Root cause: ModelLabel.SERIES — used as an IssueViewSet.cache_detail_dependent_labels entry specifically to catch Series renames — is also bumped by update_series_modified_on_issue_save() on every issue write anywhere on the site (PublisherViewSet.series_list needs that for its embedded num_issues). So any unrelated issue edit elsewhere on the site was invalidating every cached issue detail response, not just the one that changed. The same problem existed for Arc/Character/Team's issue_list via ModelLabel.ISSUE/SERIES. Both now drop those dependencies and accept bounded (24h) staleness on Series renames instead — the same tradeoff already made deliberately for Creator/Universe names.

Auditing every writer of Issue.modified to make sure no other over-broad dependency was hiding turned up the opposite problem: several fields IssueReadSerializer embeds don't bump Issue.modified at all when they change, so edits to them could go unreflected in a cached issue detail for up to 24h:

  • Adding/removing an Arc, Character, or Team from an issue only bumped the parent's modified (needed for its own issue_list cache) — the issue's own modified was never touched.
  • universes and reprints (a symmetric self-referential M2M) had no invalidation signal wired up at all.
  • Creating, editing, or deleting a Variant didn't touch its parent Issue's modified either.

All of these are now fixed with handlers scoped precisely to the pk(s) actually affected — never a blanket update, so this can't reintroduce the cross-contamination bug above. issue_ratings (average_rating/ rating_count) is deliberately left as accepted staleness — ratings are common enough that bumping on every one would undermine the cache for popular issues.

Test plan

  • Added regression tests confirming Series/Arc/Character/Team-name changes no longer bust the Issue/issue_list cache (previously-passing tests asserting the opposite were updated to assert the new, intentional staleness).
  • Added regression tests confirming adding a character, universe, reprint, or variant does invalidate the issue's cached detail response.
  • Updated two pre-existing tests whose assumptions were invalidated by the fix (a stale in-memory modified comparison, and unit tests using MagicMock(spec=Issue) where a real Issue instance is now required).

Production showed an isolated X-Cache HIT->MISS flip with no edit to the issue in question. Root cause: ModelLabel.SERIES (used as an IssueViewSet.cache_detail_dependent_labels entry to catch Series renames)
is also bumped by update_series_modified_on_issue_save() on every issue write anywhere on the site, so any unrelated issue edit was invalidating every cached issue detail response. Same problem existed for
Arc/Character/Team's issue_list via ModelLabel.ISSUE/SERIES. Both now drop those dependencies and accept bounded (24h) staleness on Series renames instead, consistent with the tradeoff already made for Creator/Universe.

Auditing every writer of Issue.modified to confirm no other over-broad dependency existed surfaced the opposite problem: several fields IssueReadSerializer embeds don't bump Issue.modified at all when they
change. update_related_modified() now also bumps the specific Issue's own `modified` (in addition to the parent Arc/Character/Team's, scoped by pk so it can't cross-contaminate other issues) when arcs/characters/teams are added or removed. New handlers cover the same gap for universes, reprints, and Variant create/update/delete. issue_ratings is deliberately left as accepted staleness -- ratings are common enough that bumping on every one would undermine the cache for popular issues.
@bpepple bpepple self-assigned this Aug 20, 2026
@bpepple bpepple added bug Something isn't working api An API bug/feature labels Aug 20, 2026
@bpepple
bpepple merged commit 13bbc24 into master Aug 20, 2026
2 checks passed
@bpepple
bpepple deleted the cache-bug-fix branch August 20, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api An API bug/feature bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant