1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-05 15:14:04 +00:00

Add tenancy maintenance mode drivers

This commit is contained in:
j.stein 2022-10-07 11:05:08 -04:00
parent 6ee93d0441
commit bb634b5326
8 changed files with 191 additions and 14 deletions

View file

@ -242,6 +242,21 @@ return [
// Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect
], ],
/**
* Maintenance mode driver
*
* These configuration options determine the driver used to determine and
* manage Tenancy's "maintenance mode" status. The "cache" driver will
* allow maintenance mode to be controlled across multiple machines.
*
* Supported drivers: "database", "cache"
*
*/
'maintenance' => [
'driver' => env('TENANCY_DATABASE_DRIVER', 'database'),
// 'store' => 'redis',
],
/** /**
* Should tenancy routes be registered. * Should tenancy routes be registered.
* *

View file

@ -4,27 +4,68 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Database\Concerns; namespace Stancl\Tenancy\Database\Concerns;
use Illuminate\Contracts\Container\BindingResolutionException;
use Stancl\Tenancy\Maintenance\TenantMaintenanceModeContract;
/** /**
* @mixin \Illuminate\Database\Eloquent\Model * @mixin \Illuminate\Database\Eloquent\Model
*/ */
trait MaintenanceMode trait MaintenanceMode
{ {
public function putDownForMaintenance($data = []): void /**
* Get an instance of the tenant maintenance mode manager implementation.
*
* @return TenantMaintenanceModeContract
* @throws BindingResolutionException
*/
public function maintenanceMode(): TenantMaintenanceModeContract
{ {
$this->update([ return app()->make(TenantMaintenanceModeContract::class);
'maintenance_mode' => [
'except' => $data['except'] ?? null,
'redirect' => $data['redirect'] ?? null,
'retry' => $data['retry'] ?? null,
'refresh' => $data['refresh'] ?? null,
'secret' => $data['secret'] ?? null,
'status' => $data['status'] ?? 503,
],
]);
} }
/**
* Put the tenant into maintenance
*
* @param array $payload
* @return void
* @throws BindingResolutionException
*/
public function putDownForMaintenance(array $payload = []): void
{
ray('down');
$this->maintenanceMode()->activate($payload);
}
/**
* Remove the tenant from maintenance
*
* @return void
* @throws BindingResolutionException
*/
public function bringUpFromMaintenance(): void public function bringUpFromMaintenance(): void
{ {
$this->update(['maintenance_mode' => null]); $this->maintenanceMode()->deactivate();
}
/**
* Determine if the tenant is in maintenance
*
* @return bool
* @throws BindingResolutionException
*/
public function isDownForMaintenance(): bool
{
return $this->maintenanceMode()->active();
}
/**
* Get the data array which was provided when the tenant was placed into maintenance.
*
* @return array
* @throws BindingResolutionException
*/
public function getMaintenanceData(): array
{
return $this->maintenanceMode()->data();
} }
} }

View file

@ -0,0 +1,9 @@
<?php
namespace Stancl\Tenancy\Maintenance;
class CacheBasedMaintenanceMode extends \Illuminate\Foundation\CacheBasedMaintenanceMode implements TenantMaintenanceModeContract
{
//
}

View file

@ -0,0 +1,37 @@
<?php
namespace Stancl\Tenancy\Maintenance;
class DatabaseBasedMaintenanceMode implements TenantMaintenanceModeContract
{
public function activate(array $payload): void
{
tenant()->update([
'maintenance_mode' => [
'except' => $payload['except'] ?? null,
'redirect' => $payload['redirect'] ?? null,
'retry' => $payload['retry'] ?? null,
'refresh' => $payload['refresh'] ?? null,
'secret' => $payload['secret'] ?? null,
'status' => $payload['status'] ?? 503,
],
]);
}
public function deactivate(): void
{
tenant()->update(['maintenance_mode' => null]);
}
public function active(): bool
{
return !is_null(tenant('maintenance_mode'));
}
public function data(): array
{
return tenant('maintenance_mode');
}
}

View file

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Maintenance;
use Illuminate\Support\Manager;
class MaintenanceModeManager extends Manager
{
/**
* Create an instance of the file based maintenance driver.
*
* @return DatabaseBasedMaintenanceMode
*/
protected function createDatabaseDriver(): DatabaseBasedMaintenanceMode
{
return new DatabaseBasedMaintenanceMode();
}
/**
* Create an instance of the cache based maintenance driver.
*
* @return CacheBasedMaintenanceMode
*
*/
protected function createCacheDriver(): CacheBasedMaintenanceMode
{
return new CacheBasedMaintenanceMode(
$this->container->make('cache'),
$this->config->get('tenancy.maintenance.store') ?: $this->config->get('cache.default'),
tenant()->getTenantKey() . ':down'
);
}
/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver(): string
{
return $this->config->get('tenancy.maintenance.driver', 'database');
}
}

View file

@ -0,0 +1,10 @@
<?php
namespace Stancl\Tenancy\Maintenance;
use Illuminate\Contracts\Foundation\MaintenanceMode;
interface TenantMaintenanceModeContract extends MaintenanceMode
{
}

View file

@ -17,8 +17,8 @@ class CheckTenantForMaintenanceMode extends CheckForMaintenanceMode
throw new TenancyNotInitializedException; throw new TenancyNotInitializedException;
} }
if (tenant('maintenance_mode')) { if (tenant()->isDownForMaintenance()) {
$data = tenant('maintenance_mode'); $data = tenant()->getMaintenanceData();
if (isset($data['secret']) && $request->path() === $data['secret']) { if (isset($data['secret']) && $request->path() === $data['secret']) {
return $this->bypassResponse($data['secret']); return $this->bypassResponse($data['secret']);

View file

@ -12,6 +12,8 @@ use Stancl\Tenancy\Contracts\Domain;
use Stancl\Tenancy\Contracts\Tenant; use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Enums\LogMode; use Stancl\Tenancy\Enums\LogMode;
use Stancl\Tenancy\Events\Contracts\TenancyEvent; use Stancl\Tenancy\Events\Contracts\TenancyEvent;
use Stancl\Tenancy\Maintenance\MaintenanceModeManager;
use Stancl\Tenancy\Maintenance\TenantMaintenanceModeContract;
use Stancl\Tenancy\Resolvers\DomainTenantResolver; use Stancl\Tenancy\Resolvers\DomainTenantResolver;
class TenancyServiceProvider extends ServiceProvider class TenancyServiceProvider extends ServiceProvider
@ -44,6 +46,8 @@ class TenancyServiceProvider extends ServiceProvider
return DomainTenantResolver::$currentDomain; return DomainTenantResolver::$currentDomain;
}); });
$this->registerMaintenanceModeManager();
// Make sure bootstrappers are stateful (singletons). // Make sure bootstrappers are stateful (singletons).
foreach ($this->app['config']['tenancy.bootstrappers'] ?? [] as $bootstrapper) { foreach ($this->app['config']['tenancy.bootstrappers'] ?? [] as $bootstrapper) {
if (method_exists($bootstrapper, '__constructStatic')) { if (method_exists($bootstrapper, '__constructStatic')) {
@ -137,4 +141,20 @@ class TenancyServiceProvider extends ServiceProvider
return $instance; return $instance;
}); });
} }
/**
* Register the maintenance mode manager service.
*
* @return void
*/
public function registerMaintenanceModeManager(): void
{
$this->app->singleton(MaintenanceModeManager::class);
$this->app->bind(
TenantMaintenanceModeContract::class,
fn () => $this->app->make(MaintenanceModeManager::class)->driver()
);
}
} }