towerops/lib/towerops/workers/cloud_latency_probe_worker.ex
Graham McIntire a61abd836c
fix: cloud poller automatic rebalancing
- create MonitoringCheck schema for the monitoring_checks table, fixing
  silent data loss where ping results were dropped by the wrong schema
- update agent channel and device monitor worker to use new schema
- fix Stats queries to use MonitoringCheck instead of Check schema
- add list_online_cloud_pollers and list_cloud_polled_devices queries
- add CloudLatencyProbeWorker to dispatch cross-agent latency probes
  every 8 hours via PubSub to all online cloud pollers
- scope AgentLatencyEvaluator to cloud pollers only with cloud_only
  filter, lower min_checks (5), wider time window (48h), and
  device-level assignments to avoid changing site/org defaults
- update cron schedule: probes at 0/8/16h, evaluation at 0:30/8:30/16:30
- refactor monitoring.ex and http_executor.ex to fix credo complexity
2026-02-12 15:32:33 -06:00

47 lines
1.3 KiB
Elixir

defmodule Towerops.Workers.CloudLatencyProbeWorker do
@moduledoc """
Oban cron worker that dispatches latency probes from all online cloud agents
to all cloud-polled devices.
Runs every 8 hours to collect cross-agent latency data used by
AgentLatencyEvaluator for automatic device reassignment.
Each cloud agent receives a list of devices to ping (5 pings per device).
Results flow back through the existing MonitoringCheck pipeline.
"""
use Oban.Worker, queue: :maintenance
alias Towerops.Agents
require Logger
@impl Oban.Worker
def perform(%Oban.Job{}) do
cloud_pollers = Agents.list_online_cloud_pollers()
devices = Agents.list_cloud_polled_devices()
if cloud_pollers == [] or devices == [] do
Logger.info("Cloud latency probe: no work (#{length(cloud_pollers)} pollers, #{length(devices)} devices)")
:ok
else
dispatch_probes(cloud_pollers, devices)
end
end
defp dispatch_probes(cloud_pollers, devices) do
Logger.info(
"Cloud latency probe: dispatching to #{length(cloud_pollers)} poller(s) " <>
"for #{length(devices)} device(s)"
)
for poller <- cloud_pollers do
Phoenix.PubSub.broadcast(
Towerops.PubSub,
"agent:#{poller.id}:latency_probe",
{:latency_probe_jobs, devices}
)
end
:ok
end
end