From 840a5938205456ec8a09bfa03205acf5b299b7f0 Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 11 Jun 2021 12:47:48 -0400 Subject: [PATCH 1/4] Add `WorkerSync` and `Defaults` classes --- app/Support/Defaults.php | 23 +++++++++++ app/Sync/WorkerSync.php | 83 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 app/Support/Defaults.php create mode 100644 app/Sync/WorkerSync.php diff --git a/app/Support/Defaults.php b/app/Support/Defaults.php new file mode 100644 index 0000000..073df73 --- /dev/null +++ b/app/Support/Defaults.php @@ -0,0 +1,23 @@ + 'default', // Note: defaults to blank if omitted + 'connection' => 'redis', // Required by Forge API + 'php_version' => $php, // Required by Forge API + 'daemon' => false, // Required by Forge API + 'processes' => 1, + 'timeout' => 60, // Note: defaults to 0 (no timeout) if omitted + 'sleep' => 10, // Required by Forge API + 'delay' => 0, + 'tries' => null, + 'environment' => null, + 'force' => false, + ]; + } +} diff --git a/app/Sync/WorkerSync.php b/app/Sync/WorkerSync.php new file mode 100644 index 0000000..575657c --- /dev/null +++ b/app/Sync/WorkerSync.php @@ -0,0 +1,83 @@ +config->get($environment, 'workers', [])); + $forgeWorkers = collect($this->forge->workers($server->id, $site->id))->keyBy('id'); + + // Create workers that are defined locally but do not exist on Forge + $workers->reject(function (array $worker) use (&$forgeWorkers, $server, $site) { + if ($match = $forgeWorkers->first(fn (Worker $forge) => $this->equivalent($server, $forge, $worker))) { + // Remove each found worker from the list of 'unmatched' workers on Forge + $forgeWorkers->forget($match->id); + + return true; + } + })->map(function (array $worker) use ($server, $site, $output) { + $data = $this->getWorkerPayload($server, $worker); + + $output->writeln("Creating {$data['queue']} queue worker on {$data['connection']} connection..."); + + $this->forge->createWorker($server->id, $site->id, $data); + }); + + if ($forgeWorkers->isNotEmpty()) { + if ($force) { + $forgeWorkers->map(function (Worker $worker) use ($server, $site, $output) { + $output->writeln("Deleting {$worker->queue} queue worker present on Forge but not listed locally..."); + + $this->forge->deleteWorker($server->id, $site->id, $worker->id); + }); + } else { + $output->writeln("Found {$forgeWorkers->count()} queue workers present on Forge but not listed locally."); + $output->writeln('Run the command again with the `--force` option to delete them.'); + } + } + } + + protected function equivalent(Server $server, Worker $worker, array $config): bool + { + $cli = collect($this->forge->phpVersions($server->id))->firstWhere('usedOnCli', true)->version; + + $defaults = Defaults::worker($cli); + + $forgeWorker = [ + 'queue' => $worker->queue, + 'connection' => $worker->connection, + 'timeout' => $worker->timeout, + 'delay' => $worker->delay, + 'sleep' => $worker->sleep, + 'tries' => $worker->tries, + 'environment' => $worker->environment, + 'daemon' => (bool) $worker->daemon, + 'force' => (bool) $worker->force, + 'php_version' => str_replace('.', '', head(explode(' ', $worker->command))), + 'processes' => $worker->processes, + ]; + + foreach (array_merge($defaults, $config) as $key => $value) { + if ($forgeWorker[$key] !== $value) { + return false; + } + } + + return true; + } + + protected function getWorkerPayload(Server $server, array $worker): array + { + $cli = collect($this->forge->phpVersions($server->id))->firstWhere('usedOnCli', true)->version; + + return array_merge(Defaults::worker($cli), $worker); + } +} From 0cad4d3e78cd6f0d80dc71b5d3c406d5ddef26a3 Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 11 Jun 2021 12:48:00 -0400 Subject: [PATCH 2/4] Update `PushConfigCommand` to sync workers --- app/Commands/PushConfigCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Commands/PushConfigCommand.php b/app/Commands/PushConfigCommand.php index 8679c70..f65c87c 100644 --- a/app/Commands/PushConfigCommand.php +++ b/app/Commands/PushConfigCommand.php @@ -20,6 +20,7 @@ class PushConfigCommand extends ForgeCommand WebhookSync::class, DeploymentScriptSync::class, DaemonSync::class, + WorkerSync::class, ]; protected $signature = 'config:push {environment=production} {--force}'; From 7c20bda6ccc3d76fb1220eca9b5bdc714249bc0f Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 11 Jun 2021 12:54:01 -0400 Subject: [PATCH 3/4] Add worker configuration --- app/Support/Configuration.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/Support/Configuration.php b/app/Support/Configuration.php index 6ddc359..9887f3d 100644 --- a/app/Support/Configuration.php +++ b/app/Support/Configuration.php @@ -70,6 +70,7 @@ protected function getConfigFormat(Server $server, Site $site) 'deployment' => explode("\n", $site->getDeploymentScript()), 'webhooks' => $this->getWebhooks($server, $site), 'daemons' => $this->getDaemons($server, $site), + 'workers' => $this->getWorkers($server, $site), ]; } @@ -96,4 +97,31 @@ protected function getDaemons(Server $server, Site $site) ]; })->values()->toArray(); } + + protected function getWorkers(Server $server, Site $site) + { + $cli = collect($this->forge->phpVersions($server->id))->firstWhere('usedOnCli', true)->version; + + $defaults = Defaults::worker($cli); + + return collect($this->forge->workers($server->id, $site->id))->map(function ($worker) use ($defaults) { + $data = [ + 'queue' => $worker->queue, + 'connection' => $worker->connection, + 'php_version' => str_replace('.', '', head(explode(' ', $worker->command))), + 'daemon' => (bool) $worker->daemon, + 'processes' => $worker->processes, + 'timeout' => $worker->timeout, + 'sleep' => $worker->sleep, + 'delay' => $worker->delay, + 'tries' => $worker->tries, + 'environment' => $worker->environment, + 'force' => (bool) $worker->force, + ]; + + $nonDefaults = collect($data)->filter(fn ($value, $key) => $value !== $defaults[$key])->keys()->toArray(); + + return Arr::only($data, ['queue', 'connection', ...$nonDefaults]); + })->toArray(); + } } From dd723e63d60fb1fa808e118fa3aebfc03d3982cb Mon Sep 17 00:00:00 2001 From: Jacob Baker-Kretzmar Date: Fri, 11 Jun 2021 13:28:24 -0400 Subject: [PATCH 4/4] Add import --- app/Commands/PushConfigCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Commands/PushConfigCommand.php b/app/Commands/PushConfigCommand.php index f65c87c..3e9e8bf 100644 --- a/app/Commands/PushConfigCommand.php +++ b/app/Commands/PushConfigCommand.php @@ -7,6 +7,7 @@ use App\Sync\DaemonSync; use App\Sync\DeploymentScriptSync; use App\Sync\WebhookSync; +use App\Sync\WorkerSync; use Illuminate\Console\Scheduling\Schedule; use Laravel\Forge\Forge; use Laravel\Forge\Resources\Server;