Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 114 additions & 5 deletions app/Jobs/Ookla/SelectSpeedtestServerJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
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
{
Expand All @@ -28,14 +31,60 @@ public function handle(): void
return;
}

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

if ($this->result->server_id != $serverId) {
$this->result->update([
'data->server->id' => $serverId,
// 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();
}

/**
Expand All @@ -56,4 +105,64 @@ private function getConfigServer(): ?string
? 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 changes: 2 additions & 0 deletions config/speedtest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

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

'blocked_servers' => env('SPEEDTEST_BLOCKED_SERVERS'),

/**
* IP filtering settings.
*/
Expand Down