CluPilotCloud/app/Provisioning/Jobs/CollectHostLoad.php

74 lines
2.7 KiB
PHP

<?php
namespace App\Provisioning\Jobs;
use App\Models\Host;
use App\Services\Proxmox\HostLoadSeries;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
/**
* Fetches the last hour of load from every host that is worth asking, and puts
* it where the console can read it.
*
* On the `provisioning` queue, and that is the whole reason this job exists:
* only that container is inside the WireGuard tunnel. The `app` container has
* no route to a host's management address, so the console cannot fetch this
* itself — it reads what this job left behind. Same rule, same queue and the
* same reason as PingHosts next door.
*
* Every minute, because that is how often Proxmox writes a fresh sample. The
* cache entry lives five minutes, so one missed run does not blank a page,
* and a collector that has stopped takes the figures with it instead of
* leaving an old hour on screen looking current.
*/
class CollectHostLoad implements ShouldBeUnique, ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* One collector at a time, fleet-wide.
*
* The `provisioning` queue is the SAME queue that carries out customer
* provisioning. A host that has gone quiet costs this job the full HTTP
* timeout, so with enough of them a minutely run is not finished when the
* next one is dispatched — and the backlog then delays work somebody has
* paid for. Same guard, same reason as CollectInstanceTraffic next door.
*/
public int $uniqueFor = 600;
/**
* A missed minute is fetched by the next minute, not by a retry of this
* one: the RRD is a rolling hour, so a repeat would ask for almost exactly
* what the following run asks for anyway.
*/
public int $tries = 1;
public function __construct()
{
$this->onQueue('provisioning');
}
public function handle(HostLoadSeries $load): void
{
// The same two states PingHosts asks about: a host still being onboarded
// has no token yet, and a retired one is nobody's dashboard. `error` is
// included deliberately — a host in trouble is exactly the one an
// operator opens the page for.
$hosts = Host::query()
->whereIn('status', ['active', 'error'])
->whereNotNull('api_token_ref')
->get();
foreach ($hosts as $host) {
// collect() logs its own failures and never throws: one unreachable
// host must not stop the collection for the rest of the fleet.
$load->collect($host);
}
}
}