helpers/CacheHelper.php (remember()) has no locking around cache-miss recomputation. If Request A starts computing stats just before a ticket mutation + invalidateCache(), and Request B starts just after the mutation (correctly computing fresh, post-mutation stats), it's possible for A to finish computing (using stale pre-mutation data) AFTER B and overwrite B's fresh cache entry — extending staleness by up to another full 60s TTL.
Window is narrow in practice (only as wide as the stats query's execution time, likely well under 100ms), and this is a genuine race rather than a design gap, but worth a low-priority fix.
Fix: Add a simple compute-generation/version check before writing the cache (only write if no newer invalidation happened since this computation started), or accept the narrow risk as-is given how small the window is — flagging for a decision either way.
**Severity:** Low
`helpers/CacheHelper.php` (`remember()`) has no locking around cache-miss recomputation. If Request A starts computing stats just before a ticket mutation + `invalidateCache()`, and Request B starts just after the mutation (correctly computing fresh, post-mutation stats), it's possible for A to finish computing (using stale pre-mutation data) AFTER B and overwrite B's fresh cache entry — extending staleness by up to another full 60s TTL.
Window is narrow in practice (only as wide as the stats query's execution time, likely well under 100ms), and this is a genuine race rather than a design gap, but worth a low-priority fix.
**Fix:** Add a simple compute-generation/version check before writing the cache (only write if no newer invalidation happened since this computation started), or accept the narrow risk as-is given how small the window is — flagging for a decision either way.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: Low
helpers/CacheHelper.php(remember()) has no locking around cache-miss recomputation. If Request A starts computing stats just before a ticket mutation +invalidateCache(), and Request B starts just after the mutation (correctly computing fresh, post-mutation stats), it's possible for A to finish computing (using stale pre-mutation data) AFTER B and overwrite B's fresh cache entry — extending staleness by up to another full 60s TTL.Window is narrow in practice (only as wide as the stats query's execution time, likely well under 100ms), and this is a genuine race rather than a design gap, but worth a low-priority fix.
Fix: Add a simple compute-generation/version check before writing the cache (only write if no newer invalidation happened since this computation started), or accept the narrow risk as-is given how small the window is — flagging for a decision either way.