71 lines
2.6 KiB
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);
|
|
}
|
|
}
|
|
}
|