Skip to content

Commit d89f40d

Browse files
authored
[Feature] Implement a blocked servers list (alexjustesen#1896)
1 parent 3337b43 commit d89f40d

File tree

2 files changed

+116
-5
lines changed

2 files changed

+116
-5
lines changed

app/Jobs/Ookla/SelectSpeedtestServerJob.php

Lines changed: 114 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
use Illuminate\Contracts\Queue\ShouldQueue;
88
use Illuminate\Foundation\Queue\Queueable;
99
use Illuminate\Support\Arr;
10+
use Illuminate\Support\Facades\Log;
11+
use Symfony\Component\Process\Exception\ProcessFailedException;
12+
use Symfony\Component\Process\Process;
1013

1114
class SelectSpeedtestServerJob implements ShouldQueue
1215
{
@@ -28,14 +31,60 @@ public function handle(): void
2831
return;
2932
}
3033

31-
$serverId = $this->result->server_id
32-
?? $this->getConfigServer();
34+
// If the server id is already set, we don't need to do anything.
35+
if (Arr::exists($this->result->data, 'server.id')) {
36+
return;
37+
}
3338

34-
if ($this->result->server_id != $serverId) {
35-
$this->result->update([
36-
'data->server->id' => $serverId,
39+
// If preferred servers are set in the config, we can use that.
40+
if (! blank(config('speedtest.servers'))) {
41+
$this->updateServerId(
42+
result: $this->result,
43+
serverId: $this->getConfigServer(),
44+
);
45+
46+
return;
47+
}
48+
49+
// If blocked servers config is blank, we can skip picking a server.
50+
if (blank(config('speedtest.blocked_servers'))) {
51+
return;
52+
}
53+
54+
$serverId = $this->filterBlockedServers();
55+
56+
if (blank($serverId)) {
57+
Log::info('Failed to select a server for Ookla speedtest, skipping blocked server filter.', [
58+
'result_id' => $this->result->id,
3759
]);
60+
61+
return;
62+
}
63+
64+
$this->updateServerId($this->result, $serverId);
65+
}
66+
67+
/**
68+
* Get a list of servers from config blocked servers.
69+
*/
70+
private function getConfigBlockedServers(): array
71+
{
72+
$blocked = config('speedtest.blocked_servers');
73+
74+
$blocked = array_filter(
75+
array_map(
76+
'trim',
77+
explode(',', $blocked),
78+
),
79+
);
80+
81+
if (blank($blocked)) {
82+
return [];
3883
}
84+
85+
return collect($blocked)->mapWithKeys(function (int $serverId) {
86+
return [$serverId => $serverId];
87+
})->toArray();
3988
}
4089

4190
/**
@@ -56,4 +105,64 @@ private function getConfigServer(): ?string
56105
? Arr::random($servers)
57106
: null;
58107
}
108+
109+
/**
110+
* Filter servers from server list.
111+
*/
112+
private function filterBlockedServers(): mixed
113+
{
114+
$blocked = $this->getConfigBlockedServers();
115+
116+
$servers = $this->listServers();
117+
118+
$filtered = Arr::except($servers, $blocked);
119+
120+
return Arr::first($filtered);
121+
}
122+
123+
/**
124+
* Get a list of servers.
125+
*/
126+
private function listServers(): array
127+
{
128+
$command = [
129+
'speedtest',
130+
'--accept-license',
131+
'--accept-gdpr',
132+
'--servers',
133+
'--format=json',
134+
];
135+
136+
$process = new Process($command);
137+
138+
try {
139+
$process->run();
140+
} catch (ProcessFailedException $e) {
141+
Log::error('Failed listing Ookla speedtest servers.', [
142+
'error' => $e->getMessage(),
143+
]);
144+
145+
return [];
146+
}
147+
148+
$servers = Arr::get(
149+
array: json_decode($process->getOutput(), true),
150+
key: 'servers',
151+
default: [],
152+
);
153+
154+
return collect($servers)->mapWithKeys(function (array $server) {
155+
return [$server['id'] => $server['id']];
156+
})->toArray();
157+
}
158+
159+
/**
160+
* Update the result with the selected server Id.
161+
*/
162+
private function updateServerId(Result $result, int $serverId): void
163+
{
164+
$result->update([
165+
'data->server->id' => $serverId,
166+
]);
167+
}
59168
}

config/speedtest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
'servers' => env('SPEEDTEST_SERVERS'),
3535

36+
'blocked_servers' => env('SPEEDTEST_BLOCKED_SERVERS'),
37+
3638
/**
3739
* IP filtering settings.
3840
*/

0 commit comments

Comments
 (0)