Skip to content

Commit f65b055

Browse files
committed
Use extend() to override database cache store creation for globalCache
Instead of looping through all database cache stores and setting their connection to central, use extend() to create the database stores lazily, using central connection
1 parent 602a151 commit f65b055

2 files changed

Lines changed: 13 additions & 36 deletions

File tree

src/Bootstrappers/DatabaseCacheBootstrapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* Notably, this bootstrapper sets TenancyServiceProvider::$adjustCacheManagerUsing to a callback
2727
* that ensures all affected stores still use the central connection when accessed via global cache
2828
* (typically the GlobalCache facade or global_cache() helper), even though this bootstrapper explicitly
29-
* sets the connection to tenant for all scoped cache stores. TenancyServiceProvider::makeDatabaseCacheStoresCentral()
29+
* sets the connection to tenant for all scoped cache stores. Extending database store on the global cache manager
3030
* cannot fix globalCache on its own because it reads 'tenant' from config (set by this bootstrapper), not null,
3131
* so the callback is still needed to correct the connection to central for globalCache.
3232
*/

src/TenancyServiceProvider.php

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66

77
use Closure;
88
use Illuminate\Cache\CacheManager;
9-
use Illuminate\Cache\DatabaseStore;
109
use Illuminate\Contracts\Container\Container;
1110
use Illuminate\Database\Console\Migrations\FreshCommand;
1211
use Illuminate\Routing\Events\RouteMatched;
13-
use Illuminate\Support\Facades\DB;
1412
use Illuminate\Support\Facades\Event;
1513
use Illuminate\Support\Facades\Route;
1614
use Illuminate\Support\ServiceProvider;
@@ -92,18 +90,25 @@ public function register(): void
9290
// to 'tenant'. A freshly created CacheManager would therefore instantiate database
9391
// stores with the tenant connection.
9492
//
95-
// For that reason, we adjust the relevant stores on this new CacheManager
96-
// using the makeDatabaseCacheStoresCentral() method and the $adjustCacheManagerUsing callback below
97-
// (set by DatabaseCacheBootstrapper).
93+
// For that reason, we override the 'database' driver creator on this manager so that
94+
// database stores are built with the central connection, and we run the
95+
// $adjustCacheManagerUsing callback below (set by DatabaseCacheBootstrapper).
9896
$manager = new CacheManager($app);
9997

10098
// When DatabaseTenancyBootstrapper is used, database stores whose 'connection'
10199
// config is null fall back to the default DB connection ('tenant'). Reset each
102100
// such store to its explicitly configured connection, or fall back to central.
103-
$this->makeDatabaseCacheStoresCentral($manager);
101+
$centralConnection = $app['config']['tenancy.database.central_connection'];
102+
103+
$manager->extend('database', function ($app, array $config) use ($centralConnection) {
104+
$config['connection'] ??= $centralConnection;
105+
106+
/** @var CacheManager $this */
107+
return $this->createDatabaseDriver($config);
108+
});
104109

105110
// DatabaseCacheBootstrapper explicitly writes 'tenant' into each store's 'connection'
106-
// config. makeDatabaseCacheStoresCentral() above would then read 'tenant' as the
111+
// config. The database store extend above would then read 'tenant' as the
107112
// configured value (not null) and use it directly, so the central connection fallback
108113
// wouldn't be used.
109114
//
@@ -116,34 +121,6 @@ public function register(): void
116121
});
117122
}
118123

119-
/**
120-
* Ensure globalCache uses the central connection for database cache stores.
121-
*
122-
* A freshly built CacheManager creates database stores using the current default connection, which
123-
* DatabaseTenancyBootstrapper switches to the tenant connection. Since global cache should always be
124-
* central, reset those stores back to their configured connection, falling back to the central one.
125-
*/
126-
protected function makeDatabaseCacheStoresCentral(CacheManager $manager): void
127-
{
128-
$centralConnection = $this->app['config']['tenancy.database.central_connection'];
129-
130-
foreach ($this->app['config']['cache.stores'] ?? [] as $name => $store) {
131-
$notAValidDatabaseStore = ! is_array($store) || ($store['driver'] ?? null) !== 'database';
132-
133-
if ($notAValidDatabaseStore) {
134-
continue;
135-
}
136-
137-
/** @var DatabaseStore $databaseStore */
138-
$databaseStore = $manager->store($name)->getStore();
139-
140-
// If $store['connection'] is null, it defaults to the default DB connection (which may be tenant).
141-
// Fall back to the central connection to keep the global cache central.
142-
$databaseStore->setConnection(DB::connection($store['connection'] ?? $centralConnection));
143-
$databaseStore->setLockConnection(DB::connection($store['lock_connection'] ?? $store['connection'] ?? $centralConnection));
144-
}
145-
}
146-
147124
/* Bootstrap services. */
148125
public function boot(): void
149126
{

0 commit comments

Comments
 (0)