CluPilotCloud/app/Provisioning/Jobs/CollectHostLoad.php

71 lines
2.6 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
{
// Who counts as collectable lives on the model, in one place: this job
// and the host page both read it, and when they disagreed, opening a
// host mid-onboarding scanned the whole fleet and still left its tiles
// empty.
$hosts = Host::query()->collectable()->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);
}
}
}