Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/TenancyServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

use Closure;
use Illuminate\Cache\CacheManager;
use Illuminate\Cache\DatabaseStore;
use Illuminate\Contracts\Container\Container;
use Illuminate\Database\Console\Migrations\FreshCommand;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
Expand Down Expand Up @@ -94,6 +96,15 @@ public function register(): void
// using the callback below. It is set by DatabaseCacheBootstrapper.
$manager = new CacheManager($app);

// Make globalCache use either the configured non-null connection,
// or fall back to the central connection.
$this->makeDatabaseCacheStoresCentral($manager);

// If a bootstrapper (like DatabaseCacheBootstrapper) makes the
// cache connection tenant explicitly, the makeDatabaseCacheStoresCentral()
// call ends up setting the tenant connection rather than the central one,
// and the $adjustCacheManagerUsing callback is needed to
// make globalCache use the central connection.
if (static::$adjustCacheManagerUsing !== null) {
(static::$adjustCacheManagerUsing)($manager);
}
Expand All @@ -102,6 +113,34 @@ public function register(): void
});
}

/**
* Ensure globalCache uses the central connection for database cache stores.
*
* A freshly built CacheManager creates database stores using the current default connection, which
* DatabaseTenancyBootstrapper switches to the tenant connection. Since global cache should always be
* central, reset those stores back to their configured connection, falling back to the central one.
*/
protected function makeDatabaseCacheStoresCentral(CacheManager $manager): void
{
$centralConnection = $this->app['config']['tenancy.database.central_connection'];

foreach ($this->app['config']['cache.stores'] ?? [] as $name => $store) {
$notAValidDatabaseStore = ! is_array($store) || ($store['driver'] ?? null) !== 'database';

if ($notAValidDatabaseStore) {
continue;
}

/** @var DatabaseStore $databaseStore */
$databaseStore = $manager->store($name)->getStore();

// If $store['connection'] is null, it defaults to the default DB connection (which may be tenant).
// Fall back to the central connection to keep the global cache central.
$databaseStore->setConnection(DB::connection($store['connection'] ?? $centralConnection));
$databaseStore->setLockConnection(DB::connection($store['lock_connection'] ?? $store['connection'] ?? $centralConnection));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}

/* Bootstrap services. */
public function boot(): void
{
Expand Down
1 change: 1 addition & 0 deletions tests/CachedTenantResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
['redis', [CacheTenancyBootstrapper::class]],
['redis', [CacheTagsBootstrapper::class]],
['database', [DatabaseTenancyBootstrapper::class, DatabaseCacheBootstrapper::class]],
['database', [DatabaseTenancyBootstrapper::class, CacheTenancyBootstrapper::class]],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
]);

test('cache is invalidated when the tenant is deleted', function (string $resolver, bool $configureTenantModelColumn) {
Expand Down
1 change: 1 addition & 0 deletions tests/GlobalCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
['redis', [CacheTagsBootstrapper::class]],
['redis', [CacheTenancyBootstrapper::class]],
['database', [DatabaseTenancyBootstrapper::class, DatabaseCacheBootstrapper::class]],
['database', [DatabaseTenancyBootstrapper::class, CacheTenancyBootstrapper::class]],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
])->with([
'helper',
'facade',
Expand Down
Loading