mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 15:14:03 +00:00
Configure globalCache's DB stores to use central connection instead of default connection every time it's reinstantiated
This commit is contained in:
parent
f5e03bff62
commit
4b823fca7d
3 changed files with 48 additions and 3 deletions
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- laravel: "^12.0"
|
||||
- laravel: "dev-dbstore-setconnection" # todo0 revert along with require (8 lines below)
|
||||
php: "8.4"
|
||||
|
||||
steps:
|
||||
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
- name: Install Composer dependencies
|
||||
run: |
|
||||
composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update
|
||||
composer require "stancl/framework:${{ matrix.laravel }}" --no-interaction --no-update
|
||||
composer update --prefer-dist --no-interaction
|
||||
- name: Run tests
|
||||
if: ${{ ! env.ACT }}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ namespace Stancl\Tenancy\Bootstrappers;
|
|||
use Exception;
|
||||
use Illuminate\Cache\CacheManager;
|
||||
use Illuminate\Config\Repository;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
||||
use Stancl\Tenancy\Contracts\Tenant;
|
||||
use Stancl\Tenancy\TenancyServiceProvider;
|
||||
|
||||
/**
|
||||
* This bootstrapper allows cache to be stored in the tenant databases by switching
|
||||
|
|
@ -55,6 +57,22 @@ class DatabaseCacheBootstrapper implements TenancyBootstrapper
|
|||
|
||||
$this->cache->purge($storeName);
|
||||
}
|
||||
|
||||
// Preferably we'd try to respect the original value of this static property -- store it in a variable,
|
||||
// pull it into the closure, and execute it there. But such a naive approach would lead to existing callbacks
|
||||
// *from here* being executed repeatedly in a loop on reinitialization. For that reason we do not do that
|
||||
// (this is our only use of $adjustCacheManagerUsing anyway) but ideally at some point we'd have a better solution.
|
||||
TenancyServiceProvider::$adjustCacheManagerUsing = function (CacheManager $manager) use ($stores) {
|
||||
foreach ($stores as $storeName) {
|
||||
$manager->store($storeName)->getStore()->setConnection(
|
||||
DB::connection($this->originalConnections[$storeName] ?? config('tenancy.database.central_connection'))
|
||||
);
|
||||
|
||||
$manager->store($storeName)->getStore()->setLockConnection(
|
||||
DB::connection($this->originalLockConnections[$storeName] ?? config('tenancy.database.central_connection'))
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function revert(): void
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
public static bool $registerForgetTenantParameterListener = true;
|
||||
public static bool $migrateFreshOverride = true;
|
||||
|
||||
/** @internal */
|
||||
public static Closure|null $adjustCacheManagerUsing = null;
|
||||
|
||||
/* Register services. */
|
||||
public function register(): void
|
||||
{
|
||||
|
|
@ -80,8 +83,32 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
return new Commands\Seed($app['db']);
|
||||
});
|
||||
|
||||
// todo0 check how the caching in the facade affects our logic here
|
||||
// todo0 check what happens if globalCache is injected - it may be
|
||||
// problematic if it's injected before adjustCacheManagerUsing
|
||||
// was used
|
||||
|
||||
$this->app->bind('globalCache', function ($app) {
|
||||
return new CacheManager($app);
|
||||
// We create a separate CacheManager to be used for "global" cache -- cache that
|
||||
// is always central, regardless of the current context.
|
||||
//
|
||||
// Importantly, we use a regular binding here, not a singleton. Thanks to that,
|
||||
// any time we resolve this cache manager, we get a *fresh* instance -- an instance
|
||||
// that was not affected by any scoping logic.
|
||||
//
|
||||
// This works great for cache stores that are *directly* scoped, like Redis or
|
||||
// any other tagged or prefixed stores, but it doesn't work for the database driver.
|
||||
//
|
||||
// When we use the DatabaseTenancyBootstrapper, it changes the default connection,
|
||||
// and therefore the connection of the database store that will be created when
|
||||
// this new CacheManager is instantiated again.
|
||||
$manager = new CacheManager($app);
|
||||
|
||||
if (static::$adjustCacheManagerUsing !== null) {
|
||||
(static::$adjustCacheManagerUsing)($manager);
|
||||
}
|
||||
|
||||
return $manager;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue