[Feature] Implement a blocked servers list (#1896)

This commit is contained in:
Alex Justesen
2024-12-11 17:42:27 -05:00
committed by GitHub
parent 3337b43297
commit d89f40dc4f
2 changed files with 118 additions and 7 deletions
+116 -7
View File
@@ -7,6 +7,9 @@ use Illuminate\Bus\Batchable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
class SelectSpeedtestServerJob implements ShouldQueue
{
@@ -28,14 +31,60 @@ class SelectSpeedtestServerJob implements ShouldQueue
return;
}
$serverId = $this->result->server_id
?? $this->getConfigServer();
if ($this->result->server_id != $serverId) {
$this->result->update([
'data->server->id' => $serverId,
]);
// If the server id is already set, we don't need to do anything.
if (Arr::exists($this->result->data, 'server.id')) {
return;
}
// If preferred servers are set in the config, we can use that.
if (! blank(config('speedtest.servers'))) {
$this->updateServerId(
result: $this->result,
serverId: $this->getConfigServer(),
);
return;
}
// If blocked servers config is blank, we can skip picking a server.
if (blank(config('speedtest.blocked_servers'))) {
return;
}
$serverId = $this->filterBlockedServers();
if (blank($serverId)) {
Log::info('Failed to select a server for Ookla speedtest, skipping blocked server filter.', [
'result_id' => $this->result->id,
]);
return;
}
$this->updateServerId($this->result, $serverId);
}
/**
* Get a list of servers from config blocked servers.
*/
private function getConfigBlockedServers(): array
{
$blocked = config('speedtest.blocked_servers');
$blocked = array_filter(
array_map(
'trim',
explode(',', $blocked),
),
);
if (blank($blocked)) {
return [];
}
return collect($blocked)->mapWithKeys(function (int $serverId) {
return [$serverId => $serverId];
})->toArray();
}
/**
@@ -56,4 +105,64 @@ class SelectSpeedtestServerJob implements ShouldQueue
? Arr::random($servers)
: null;
}
/**
* Filter servers from server list.
*/
private function filterBlockedServers(): mixed
{
$blocked = $this->getConfigBlockedServers();
$servers = $this->listServers();
$filtered = Arr::except($servers, $blocked);
return Arr::first($filtered);
}
/**
* Get a list of servers.
*/
private function listServers(): array
{
$command = [
'speedtest',
'--accept-license',
'--accept-gdpr',
'--servers',
'--format=json',
];
$process = new Process($command);
try {
$process->run();
} catch (ProcessFailedException $e) {
Log::error('Failed listing Ookla speedtest servers.', [
'error' => $e->getMessage(),
]);
return [];
}
$servers = Arr::get(
array: json_decode($process->getOutput(), true),
key: 'servers',
default: [],
);
return collect($servers)->mapWithKeys(function (array $server) {
return [$server['id'] => $server['id']];
})->toArray();
}
/**
* Update the result with the selected server Id.
*/
private function updateServerId(Result $result, int $serverId): void
{
$result->update([
'data->server->id' => $serverId,
]);
}
}
+2
View File
@@ -33,6 +33,8 @@ return [
'servers' => env('SPEEDTEST_SERVERS'),
'blocked_servers' => env('SPEEDTEST_BLOCKED_SERVERS'),
/**
* IP filtering settings.
*/