An availability target's configured poll interval only seeded the
adaptive scheduler: BuildPlan derived every instance's cadence from the
global adaptive bounds, and a failing probe raised the staleness score
and error penalty, collapsing the probe interval toward the global
5-second minimum. With interval 120s and failure threshold 4 the alert
was promised after ~8 minutes of downtime but fired within the first
minute because the four consecutive failures accumulated at the
collapsed cadence (#1582).
Availability checks promise pollInterval x failureThreshold as the
detection window, so the cadence is a user contract, not a scheduling
hint. Add a FixedIntervalPollProvider extension that pins an instance
to its configured interval, implement it for availability targets, and
bypass adaptive selection wherever the next run is computed (plan
building, rescheduling, and the non-adaptive fallback paths).
Clears the six dupl pairs in internal/monitoring:
- poll_providers.go: PVE/PBS/PMG listInstances / describeInstances /
connectionStatus closures collapse into generic sortedClientNames,
describeProviderInstances, and providerConnectionStatuses helpers; the
PBS/PMG adapters are now built by newPrefixedPollProvider from a
prefixedPollProviderSpec (prefix drives status keys, health keys, and
the fallback instance name).
- truenas_poller.go / vmware_poller.go: the Start scheduling loop
(double-start guard, stopped-channel handshake, sync+poll cadence)
moves to startPollerLoop, and the active-connection config policy
(enabled instances keyed by trimmed connection ID, defaults applied)
moves to loadActiveInstanceConfigs, both in the new
platform_poller_shared.go.
- monitor_polling_vm.go / monitor_polling_containers.go: traditional
polling now records guest series via the existing canonical
recordGuestMetric helper (io/network sentinels preserve the historical
cpu/memory/disk-only behavior on this path); the source-shape
guardrails in canonical_guardrails_test.go and
memory_source_catalog_test.go pin the new delegation.
- mock_metrics_history.go: native and TrueNAS disk seeding share one
seedDiskTelemetry closure.
Proof: new TestTrueNASPollerDoubleStartKeepsSingleLoop pins the shared
lifecycle loop; new TestSeedMockMetricsHistory_DiskTelemetryParityAcrossNativeAndTrueNAS
pins four-series parity for both disk sources. Contract Extension Points
name the shared wiring layer and poller scaffold.
Full internal/monitoring test suite passes.