Issue with Invalidating Tenant Cache when Redis Data Separation is Enabled
Bug description
According to the documentation, updating and saving a Tenant Model's attributes should invalidate the cache entry for this model when DomainTenantResolver::$shouldCache is set to true. This expected behavior does not occur when Redis Data Separation is enabled. However, the cache invalidation works correctly if Redis Data Separation is disabled.
Temporary Workaround: As a temporary workaround, I created a TenantObserver class that invalidates the cache by using the Redis FLUSHDB command. This approach ensures the cache is cleared; however, it has a significant drawback as it invalidates the cache for all tenants, which is not ideal
class TenantObserver
{
public function updated(Tenant $model)
{
Illuminate\Support\Facades\Redis::connection('cache')->command('FLUSHDB');
}
}
Tenant::observe(TenantObserver::class);
Steps to reproduce
- Enable Redis Data Separation (
cacheRedis DB connection): tenancy config file:
...
'redis' => [
'prefix_base' => 'tenant',
'prefixed_connection' => [
//'default',
'cache', // enabled it here
//'gracenote',
],
],
...
database config file:
...
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'scheme' => 'tcp',
// 'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
// 'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
// 'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
// 'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => '10',
],
],
...
- Set DomainTenantResolver::$shouldCache to true. in \App\Tenancy\TenancyServiceProvider::boot:
// TenancyServiceProvider::boot()
use Stancl\Tenancy\Resolvers;
DomainTenantResolver::$shouldCache = true;
DomainTenantResolver::$cacheStore = 'redis';
- Update and save a Tenant Model's attributes.
- Observe that the cache entry for the Tenant Model is not invalidated.
they cache that fails to get invalidated is the one for
DomainTenantResolver, I noticed that it does not start with the tenant id prefix, so instead of they cache key starting withtenantXapp_cache:..it starts withapp_database_app_cache:... - Disable Redis Data Separation by commenting out in the config tenancy.php
redis.prefixed_connection.cache - Repeat steps 3-4 and observe that the cache entry is correctly invalidated.
Expected behavior
When Redis Data Separation is enabled, updating and saving a Tenant Model's attributes should invalidate the cache entry for the model, similar to when Redis Data Separation is disabled.
Laravel version
9.5.2.16
stancl/tenancy version
3.8.4