mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
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.
This commit is contained in:
@@ -15,11 +15,17 @@ 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
|
||||
|
||||
@@ -64,6 +64,6 @@ class DeployServiceApplication
|
||||
$commands->push("docker network connect --alias {$networkAlias} {$network} {$containerName} >/dev/null 2>&1 || true");
|
||||
}
|
||||
|
||||
return remote_process($commands->toArray(), $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged');
|
||||
return remote_process($commands->toArray(), $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged', queue: deployment_queue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class StartService
|
||||
}
|
||||
$commands = array_merge($commands, $this->logDrainNetworkConnectCommands($service));
|
||||
|
||||
return remote_process($commands, $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged');
|
||||
return remote_process($commands, $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged', queue: deployment_queue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,7 @@ class CoolifyTask implements ShouldBeEncrypted, ShouldQueue
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param int|null $timeout Job timeout in seconds; null keeps the default above.
|
||||
* @param string $queue Queue to run on; start actions pass deployment_queue().
|
||||
*/
|
||||
public function __construct(
|
||||
public Activity $activity,
|
||||
@@ -45,12 +46,13 @@ class CoolifyTask implements ShouldBeEncrypted, ShouldQueue
|
||||
public $call_event_on_finish,
|
||||
public $call_event_data,
|
||||
?int $timeout = null,
|
||||
string $queue = 'high',
|
||||
) {
|
||||
if ($timeout !== null) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
$this->onQueue('high');
|
||||
$this->onQueue($queue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,6 @@ trait ExecutesDatabaseStartCommands
|
||||
return app(DatabaseStartCommandExecutor::class)->execute($commands, $database, $activity);
|
||||
}
|
||||
|
||||
return remote_process($commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||
return remote_process($commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged', queue: deployment_queue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ function remote_process(
|
||||
$callEventData = null,
|
||||
array $properties = [],
|
||||
?int $timeout = null,
|
||||
string $queue = 'high',
|
||||
): Activity {
|
||||
$type = $type ?? ActivityTypes::INLINE->value;
|
||||
$command = $command instanceof Collection ? $command->toArray() : $command;
|
||||
@@ -74,6 +75,7 @@ function remote_process(
|
||||
call_event_on_finish: $callEventOnFinish,
|
||||
call_event_data: $callEventData,
|
||||
timeout: $timeout,
|
||||
queue: $queue,
|
||||
));
|
||||
|
||||
$activity->refresh();
|
||||
|
||||
@@ -4,6 +4,7 @@ use App\Actions\Service\DeployServiceApplication;
|
||||
use App\Actions\Service\StartService;
|
||||
use App\Actions\Shared\EnsureContentFilesOnServer;
|
||||
use App\Jobs\ApplicationDeploymentJob;
|
||||
use App\Jobs\CoolifyTask;
|
||||
use App\Jobs\ServerStorageSaveJob;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationDeploymentQueue;
|
||||
@@ -579,3 +580,22 @@ test('the server file sync still marks a storage without content as a directory'
|
||||
|
||||
expect($volume->fresh()->is_directory)->toBeTruthy();
|
||||
});
|
||||
|
||||
test('starting a service runs its commands on the deployment queue', function (bool $selfHosted, string $queue) {
|
||||
config(['constants.coolify.self_hosted' => $selfHosted]);
|
||||
$service = Service::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'server_id' => $this->server->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
'docker_compose_raw' => "services:\n app:\n image: nginx:alpine\n",
|
||||
]);
|
||||
fakeContentFilesServer([]);
|
||||
|
||||
StartService::run($service);
|
||||
|
||||
Bus::assertDispatched(CoolifyTask::class, fn (CoolifyTask $job) => $job->queue === $queue);
|
||||
})->with([
|
||||
'cloud' => [false, 'deployments'],
|
||||
'self-hosted' => [true, 'high'],
|
||||
]);
|
||||
|
||||
@@ -85,3 +85,19 @@ it('removes the command when the task fails permanently', function () {
|
||||
expect($stored->getExtraProperty('command'))->toBeNull()
|
||||
->and($stored->getExtraProperty('status'))->toBe(ProcessStatus::ERROR->value);
|
||||
});
|
||||
|
||||
it('queues a remote process on the high queue by default', function () {
|
||||
Queue::fake();
|
||||
|
||||
remote_process(['echo ok'], $this->server);
|
||||
|
||||
Queue::assertPushedOn('high', CoolifyTask::class);
|
||||
});
|
||||
|
||||
it('queues a remote process on the requested queue', function () {
|
||||
Queue::fake();
|
||||
|
||||
remote_process(['echo ok'], $this->server, queue: 'deployments');
|
||||
|
||||
Queue::assertPushedOn('deployments', CoolifyTask::class);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Actions\Database\RestartDatabase;
|
||||
use App\Actions\Database\StartDatabase;
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Service\StartService;
|
||||
@@ -42,6 +43,7 @@ describe('start action job routing', function () {
|
||||
expect($actionClass::makeJob()->queue)->toBe('deployments');
|
||||
})->with([
|
||||
StartDatabase::class,
|
||||
RestartDatabase::class,
|
||||
StartDatabaseProxy::class,
|
||||
StartService::class,
|
||||
]);
|
||||
@@ -52,6 +54,7 @@ describe('start action job routing', function () {
|
||||
expect($actionClass::makeJob()->queue)->toBe('high');
|
||||
})->with([
|
||||
StartDatabase::class,
|
||||
RestartDatabase::class,
|
||||
StartDatabaseProxy::class,
|
||||
StartService::class,
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user