Skip to content

fix: CachedEnforcer WatcherEx callback broken — causes stale cache in multi-instance setups#1736

Open
daviediao-code wants to merge 3 commits into
apache:masterfrom
daviediao-code:pr/fix-cached-watcherex
Open

fix: CachedEnforcer WatcherEx callback broken — causes stale cache in multi-instance setups#1736
daviediao-code wants to merge 3 commits into
apache:masterfrom
daviediao-code:pr/fix-cached-watcherex

Conversation

@daviediao-code

Copy link
Copy Markdown

Problem

When CachedEnforcer is used with a WatcherEx (e.g., Redis watcher for distributed cache invalidation), the SetWatcher() callback is never set. This means when another instance modifies the policy, the cache is never invalidated, and stale decisions are returned forever.

Root Cause

Enforcer.SetWatcher() (enforcer.go:249) explicitly skips setting a callback for WatcherEx implementations.

Fix

Override SetWatcher() in both CachedEnforcer and SyncedCachedEnforcer to set a callback even for WatcherEx. The callback calls InvalidateCache() + LoadPolicy().

Files Changed

  • enforcer_cached.go: SetWatcher override with WatcherEx-aware callback
  • enforcer_cached_synced.go: Same fix for SyncedCachedEnforcer
  • enforcer_cached_watcher_test.go: 5 new tests

Tests

All existing tests pass (18s). New tests cover WatcherEx callback, basic Watcher callback, direct InvalidateCache, and TTL behavior.

PR #1729

…ache invalidation

When SetWatcher is called with a WatcherEx implementation (e.g., Redis
watcher), the callback was previously not set, causing distributed cache
invalidation to silently fail. This meant that when another instance
modified the policy, the local CachedEnforcer would continue returning
stale cached decisions.

Fix:
- Override SetWatcher in CachedEnforcer to always set a callback,
  even for WatcherEx implementations
- The callback calls InvalidateCache() + LoadPolicy() for efficient
  cache clearing on policy changes
- Same fix applied to SyncedCachedEnforcer
- Add comprehensive tests for WatcherEx callback behavior

Co-Authored-By: davie
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