Skip to content

Conversation

@alonexy
Copy link
Contributor

@alonexy alonexy commented May 28, 2025

feat: Add Redis caching layer for policies
This commit introduces a Redis caching layer to the DBAL adapter to improve performance and reduce database load.

Features:

  • Policies loaded via loadPolicy and loadFilteredPolicy are now cached in Redis.
  • Configurable Redis connection parameters (host, port, password, database, TTL, prefix).
  • Automatic cache invalidation for the main policy cache (all_policies) when policies are modified.
  • A preheatCache() method to proactively load all policies into Redis.
  • The adapter remains fully functional if Redis is not configured.

Includes:

  • Updates to Adapter.php to integrate caching logic.
  • Addition of predis/predis as a dependency.
  • Unit tests for the caching functionality in AdapterWithRedisTest.php.
  • Documentation in README.md for the new feature.

Known limitations:

  • Cache invalidation for loadFilteredPolicy currently only clears the global all_policies key, not specific filtered policy keys, to avoid using KEYS in production with Predis.

google-labs-jules bot and others added 5 commits May 28, 2025 02:35
This commit introduces a Redis caching layer to the DBAL adapter to improve performance and reduce database load.

Features:
- Policies loaded via `loadPolicy` and `loadFilteredPolicy` are now cached in Redis.
- Configurable Redis connection parameters (host, port, password, database, TTL, prefix).
- Automatic cache invalidation for the main policy cache (`all_policies`) when policies are modified.
- A `preheatCache()` method to proactively load all policies into Redis.
- The adapter remains fully functional if Redis is not configured.

Includes:
- Updates to `Adapter.php` to integrate caching logic.
- Addition of `predis/predis` as a dependency.
- Unit tests for the caching functionality in `AdapterWithRedisTest.php`.
- Documentation in `README.md` for the new feature.

Known limitations:
- Cache invalidation for `loadFilteredPolicy` currently only clears the global `all_policies` key, not specific filtered policy keys, to avoid using `KEYS` in production with Predis.
I've updated the README.md to provide more distinct and clearer examples for initializing the DBAL adapter:

- I clarified basic usage without Redis, showcasing backward compatibility by omitting Redis configuration.
- I improved the section on Redis caching usage, ensuring the example for initialization with Redis is clear.
- I renamed sections for better discoverability of these usage patterns.
@leeqvip
Copy link
Member

leeqvip commented May 29, 2025

@alonexy please fix test error

This commit refactors `AdapterWithRedisTest.php` to use a PHPUnit mock for the `Predis\Client`.
This allows testing the Redis-dependent caching logic of the `Adapter` without requiring a live Redis instance.

Key changes include:
- Modified `Adapter.php` to allow injection of a `Predis\Client` instance (or a config array). The constructor and `newAdapter` method now accept `mixed $redisOptions`.
- Updated `AdapterWithRedisTest.php`:
    - `setUp()` now creates a mock `PredisClient`.
    - Test methods (`testLoadPolicyCachesData`, etc.) were updated to configure and expect interactions with this mock client.
    - `getAdapterWithRedis()` now passes the mock client to the Adapter.

Current Test Status for AdapterWithRedisTest.php:
- Passing (2/6):
    - `testAdapterWorksWithoutRedis`
    - `testLoadPolicyCachesData`
- Failing (3/6):
    - `testCacheInvalidationOnAddPolicy`: Fails due to mock expectation sequence for cache clearing and verification (final `exists` call not reached).
    - `testCacheInvalidationOnSavePolicy`: Similar to above.
    - `testPreheatCachePopulatesCache`: Fails as `setex` is not called, likely due to issues with data seeding/retrieval with the in-memory DB for the preheat scenario.
- Error (1/6):
    - `testLoadFilteredPolicyCachesData`: Errors with `Call to undefined method Casbin\Persist\Adapters\Filter::getPredicates()`. This appears to be an external API incompatibility with the current version of `casbin/casbin` or a misconfiguration of the Filter object in the test.

Further work may be needed to resolve the failing tests, potentially by refining mock interaction sequences or addressing the in-memory DB behavior for `testPreheatCachePopulatesCache`. The `Filter::getPredicates()` error may require changes to `testLoadFilteredPolicyCachesData` according to the library's API.
@alonexy alonexy closed this May 30, 2025
@alonexy alonexy deleted the feature/redis-caching branch May 30, 2025 02:02
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.

2 participants