Files
coolify/app/Actions/Database/RestartDatabase.php
T
Andras Bacsai f1f7272494 fix(queue): run service and database start commands on the deployment queue
On cloud, StartService and DeployServiceApplication dispatched their
CoolifyTask on the high queue, so service starts competed with all other
high jobs. remote_process() and CoolifyTask now accept a queue (default
high); start paths pass deployment_queue(). The queued RestartDatabase
action also runs on deployment_queue() instead of the default queue.
2026-10-03 20:50:49 +02:00

80 lines
3.4 KiB
PHP

<?php
namespace App\Actions\Database;
use App\Exceptions\RemoteSecretException;
use App\Models\StandaloneClickhouse;
use App\Models\StandaloneDragonfly;
use App\Models\StandaloneKeydb;
use App\Models\StandaloneMariadb;
use App\Models\StandaloneMongodb;
use App\Models\StandaloneMysql;
use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis;
use App\Models\StandaloneSqlite;
use App\Support\DatabaseOperationReservation;
use App\Support\ResourceStartActivity;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\Decorators\JobDecorator;
class RestartDatabase
{
use AsAction;
public function configureJob(JobDecorator $job): void
{
$job->onQueue(deployment_queue());
}
/**
* @param string|null $reservation The token from StartDatabase::reserveOperation(). The request
* that queued this action holds the reservation; this action
* keeps it during the stop and releases it after the start.
*/
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|StandaloneSqlite $database, ?string $reservation = null)
{
if ($reservation === null) {
$reservation = DatabaseOperationReservation::acquire($database->uuid);
if ($reservation === null) {
return ResourceStartActivity::DATABASE_OPERATION_IN_PROGRESS_MESSAGE;
}
} elseif (! DatabaseOperationReservation::renew($database->uuid, $reservation)) {
// Do not stop the database for a request that expired in the queue.
return StartDatabase::operationInProgressError($database) ?? DatabaseOperationReservation::EXPIRED_MESSAGE;
}
try {
$server = $database->destination->server;
if (! $server->isFunctional()) {
return 'Server is not functional';
}
$busyError = StartDatabase::operationInProgressError($database, $reservation);
if ($busyError !== null) {
return $busyError;
}
$prerequisiteError = StartDatabase::prerequisiteError($database);
if ($prerequisiteError !== null) {
return $prerequisiteError;
}
// Check remote secrets before stopping: if the secret manager fails, the database keeps running.
try {
$database->ensureRemoteSecretsResolvable($database->runtime_environment_variables()->get());
} catch (RemoteSecretException $e) {
return $e->getMessage();
}
StopDatabase::run($database, dockerCleanup: false);
// The stop can take a while; keep the reservation for the start that follows.
DatabaseOperationReservation::renew($database->uuid, $reservation);
return StartDatabase::run($database, $reservation);
} finally {
DatabaseOperationReservation::release($database->uuid, $reservation);
}
}
public function asJob(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|StandaloneSqlite $database, ?string $reservation = null): mixed
{
return StartDatabase::runQueued($database, 'Database restart failed.', fn (): mixed => $this->handle($database, $reservation));
}
}