Skip to content

fix(core): scope CacheInvalidator lifetime and clear rolled-back pending entries - #2603

Open
wakqasahmed wants to merge 1 commit into
lunarphp:2.xfrom
wakqasahmed:fix/cache-invalidator-rollback-2561
Open

fix(core): scope CacheInvalidator lifetime and clear rolled-back pending entries#2603
wakqasahmed wants to merge 1 commit into
lunarphp:2.xfrom
wakqasahmed:fix/cache-invalidator-rollback-2561

Conversation

@wakqasahmed

Copy link
Copy Markdown

Closes #2561

Summary

CacheInvalidator is documented as request-scoped but was bound as a singleton, letting pending state outlive a request/job under Octane or long-lived workers. It's now bound with $app->scoped(...).

Separately, record() added targets to $pending and registered an afterCommit callback, but a rollback discarded the callback while leaving the $pending entry in place. A later autocommit mutation, a later committed transaction, or a later transaction touching the same target could then flush an invalidation event for a change that was rolled back.

The fix tracks the transaction level each pending entry was first (or most shallowly) touched at, and listens for Illuminate\Database\Events\TransactionRolledBack per connection to drop only the entries whose shallowest touch happened inside the frame being discarded. An entry also touched by a surviving outer frame is kept (accepted over-invalidation, consistent with the class's existing reliability bias documented in its docblock).

Changes

  • packages/core/src/LunarServiceProvider.php: bind CacheInvalidator as scoped instead of singleton.
  • packages/core/src/Cache/CacheInvalidator.php: record the transaction level per pending entry and register a rollback listener that prunes entries whose frame was discarded.
  • tests/core/Feature/CacheInvalidationTest.php: added regression coverage for
    • root rollback followed by an autocommit mutation
    • root rollback followed by a later committed transaction
    • a later transaction for the same target after a rollback
    • nested rollback followed by outer commit
    • the same target touched in both outer and nested frames surviving a nested rollback

Test plan

  • Reproduced the bug: reverting the source changes while keeping the new tests fails a root rollback does not leak into a later autocommit mutation (event dispatched 2 times instead of 1).
  • All 25 tests in tests/core/Feature/CacheInvalidationTest.php pass with the fix applied (ran via vendor/bin/pest, PHP 8.4, sqlite).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant