Skip to content

Commit b425f47

Browse files
authored
Merge pull request #20 from bakerkretzmar/add-workers
Add support for Forge workers
2 parents 406135b + dd723e6 commit b425f47

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

app/Commands/PushConfigCommand.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use App\Sync\DaemonSync;
88
use App\Sync\DeploymentScriptSync;
99
use App\Sync\WebhookSync;
10+
use App\Sync\WorkerSync;
1011
use Illuminate\Console\Scheduling\Schedule;
1112
use Laravel\Forge\Forge;
1213
use Laravel\Forge\Resources\Server;
@@ -20,6 +21,7 @@ class PushConfigCommand extends ForgeCommand
2021
WebhookSync::class,
2122
DeploymentScriptSync::class,
2223
DaemonSync::class,
24+
WorkerSync::class,
2325
];
2426

2527
protected $signature = 'config:push {environment=production} {--force}';

app/Support/Configuration.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ protected function getConfigFormat(Server $server, Site $site)
7272
'deployment' => $site->getDeploymentScript(),
7373
'webhooks' => $this->getWebhooks($server, $site),
7474
'daemons' => $this->getDaemons($server, $site),
75+
'workers' => $this->getWorkers($server, $site),
7576
];
7677
}
7778

@@ -98,4 +99,31 @@ protected function getDaemons(Server $server, Site $site)
9899
];
99100
})->values()->toArray();
100101
}
102+
103+
protected function getWorkers(Server $server, Site $site)
104+
{
105+
$cli = collect($this->forge->phpVersions($server->id))->firstWhere('usedOnCli', true)->version;
106+
107+
$defaults = Defaults::worker($cli);
108+
109+
return collect($this->forge->workers($server->id, $site->id))->map(function ($worker) use ($defaults) {
110+
$data = [
111+
'queue' => $worker->queue,
112+
'connection' => $worker->connection,
113+
'php_version' => str_replace('.', '', head(explode(' ', $worker->command))),
114+
'daemon' => (bool) $worker->daemon,
115+
'processes' => $worker->processes,
116+
'timeout' => $worker->timeout,
117+
'sleep' => $worker->sleep,
118+
'delay' => $worker->delay,
119+
'tries' => $worker->tries,
120+
'environment' => $worker->environment,
121+
'force' => (bool) $worker->force,
122+
];
123+
124+
$nonDefaults = collect($data)->filter(fn ($value, $key) => $value !== $defaults[$key])->keys()->toArray();
125+
126+
return Arr::only($data, ['queue', 'connection', ...$nonDefaults]);
127+
})->toArray();
128+
}
101129
}

app/Support/Defaults.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\Support;
4+
5+
class Defaults
6+
{
7+
public static function worker(string $php): array
8+
{
9+
return [
10+
'queue' => 'default', // Note: defaults to blank if omitted
11+
'connection' => 'redis', // Required by Forge API
12+
'php_version' => $php, // Required by Forge API
13+
'daemon' => false, // Required by Forge API
14+
'processes' => 1,
15+
'timeout' => 60, // Note: defaults to 0 (no timeout) if omitted
16+
'sleep' => 10, // Required by Forge API
17+
'delay' => 0,
18+
'tries' => null,
19+
'environment' => null,
20+
'force' => false,
21+
];
22+
}
23+
}

app/Sync/WorkerSync.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
namespace App\Sync;
4+
5+
use App\Support\Defaults;
6+
use Illuminate\Console\OutputStyle;
7+
use Laravel\Forge\Resources\Server;
8+
use Laravel\Forge\Resources\Site;
9+
use Laravel\Forge\Resources\Worker;
10+
11+
class WorkerSync extends BaseSync
12+
{
13+
public function sync(string $environment, Server $server, Site $site, OutputStyle $output, bool $force = false): void
14+
{
15+
$workers = collect($this->config->get($environment, 'workers', []));
16+
$forgeWorkers = collect($this->forge->workers($server->id, $site->id))->keyBy('id');
17+
18+
// Create workers that are defined locally but do not exist on Forge
19+
$workers->reject(function (array $worker) use (&$forgeWorkers, $server, $site) {
20+
if ($match = $forgeWorkers->first(fn (Worker $forge) => $this->equivalent($server, $forge, $worker))) {
21+
// Remove each found worker from the list of 'unmatched' workers on Forge
22+
$forgeWorkers->forget($match->id);
23+
24+
return true;
25+
}
26+
})->map(function (array $worker) use ($server, $site, $output) {
27+
$data = $this->getWorkerPayload($server, $worker);
28+
29+
$output->writeln("Creating {$data['queue']} queue worker on {$data['connection']} connection...");
30+
31+
$this->forge->createWorker($server->id, $site->id, $data);
32+
});
33+
34+
if ($forgeWorkers->isNotEmpty()) {
35+
if ($force) {
36+
$forgeWorkers->map(function (Worker $worker) use ($server, $site, $output) {
37+
$output->writeln("Deleting {$worker->queue} queue worker present on Forge but not listed locally...");
38+
39+
$this->forge->deleteWorker($server->id, $site->id, $worker->id);
40+
});
41+
} else {
42+
$output->writeln("Found {$forgeWorkers->count()} queue workers present on Forge but not listed locally.");
43+
$output->writeln('Run the command again with the `--force` option to delete them.');
44+
}
45+
}
46+
}
47+
48+
protected function equivalent(Server $server, Worker $worker, array $config): bool
49+
{
50+
$cli = collect($this->forge->phpVersions($server->id))->firstWhere('usedOnCli', true)->version;
51+
52+
$defaults = Defaults::worker($cli);
53+
54+
$forgeWorker = [
55+
'queue' => $worker->queue,
56+
'connection' => $worker->connection,
57+
'timeout' => $worker->timeout,
58+
'delay' => $worker->delay,
59+
'sleep' => $worker->sleep,
60+
'tries' => $worker->tries,
61+
'environment' => $worker->environment,
62+
'daemon' => (bool) $worker->daemon,
63+
'force' => (bool) $worker->force,
64+
'php_version' => str_replace('.', '', head(explode(' ', $worker->command))),
65+
'processes' => $worker->processes,
66+
];
67+
68+
foreach (array_merge($defaults, $config) as $key => $value) {
69+
if ($forgeWorker[$key] !== $value) {
70+
return false;
71+
}
72+
}
73+
74+
return true;
75+
}
76+
77+
protected function getWorkerPayload(Server $server, array $worker): array
78+
{
79+
$cli = collect($this->forge->phpVersions($server->id))->firstWhere('usedOnCli', true)->version;
80+
81+
return array_merge(Defaults::worker($cli), $worker);
82+
}
83+
}

0 commit comments

Comments
 (0)