B4: probe task store, panel API, heartbeat ingestion, agent prober

- probe package: probe_ping_task/probe_ping_node tables; task CRUD
  with hub save semantics (id high-water, base-diff assignment,
  64-per-agent crowding refusal, auto_join cap); filing with
  assignment-gated insert; PingHistory weighted-median chart read
  over minute+hour tiers; auto-join on first Record (ensureRows).
- controller: /panel/api/agent/probe-tasks* management endpoints
  (node id space, hub validation chain verbatim); series=ping now
  serves real rows from probe.PingHistory; heartbeat ingests
  probeResults (missing latency skipped, batch capped); config
  response carries probe_tasks (always present, empty = clear).
- agent: per-task probe loops (immediate first probe, ticker,
  900ms resolve/dial budgets, <=3 addresses, resolve overrun = no
  sample), result buffer drained on heartbeat and requeued on
  failure; task set applied before the config-hash early return.
This commit is contained in:
Muse
2026-10-22 21:57:23 +00:00
parent 540c05b0a5
commit e03ceaa41f
11 changed files with 1582 additions and 6 deletions
+23
View File
@@ -150,6 +150,29 @@ CREATE TABLE IF NOT EXISTS probe_ping_hour (
hi INTEGER,
PRIMARY KEY (agent_id, ts, task_id)
) WITHOUT ROWID;
-- Probe tasks and their per-agent assignment (hub "ping_task" /
-- "ping_node"). B4 adds both. A task is one operator-maintained
-- target — there is no preset list; region is the operator's own
-- grouping label (empty = ungrouped). Ids come from a high-water
-- mark in probe_setting so a deleted task's id is never reissued
-- (hub next_id discipline): in-flight results and an editor opened
-- before the delete must not land on a different task.
CREATE TABLE IF NOT EXISTS probe_ping_task (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
target TEXT NOT NULL,
interval INTEGER NOT NULL DEFAULT 60,
auto_join INTEGER NOT NULL DEFAULT 0,
sort INTEGER NOT NULL DEFAULT 0,
region TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS probe_ping_node (
task_id INTEGER NOT NULL,
agent_id INTEGER NOT NULL,
PRIMARY KEY (task_id, agent_id)
);
`
// Store is one open probe.db. The zero value is not usable; call Open.