Show egress/ingress levels in the registry; freeze checks at the verdict
Registry: the "last result" column now also shows, per level (egress,
ingress), how many of the recorded checks of the latest cycle succeeded, split
by check family (tcp-22 and tcp-443 are both "tcp"). One grouped query per
chunk of addresses; new fields last_cycle_id, egress, ingress in
GET /admin/registry; the dashboard renders them under the verdict.
Verdict integrity (migration 0010):
- the prober is handed an address once per site and attempt, not on every
poll, so results are no longer overwritten by later probe rounds;
- UpsertCheckIfOpen refuses writes once the address is aggregating or has its
verdict, or for an older attempt; senders get {"ok":true,"ignored":N} and a
result_dropped event is recorded;
- the checking window counts from checking_started_at, not from assigned_at;
- checks.recorded_at (server clock) and checks.after_verdict (flag for rows
written after the verdict in existing data);
- the verdict rule is a pure function (computeVerdict) and the aggregated
event carries the egress/ingress check counts.
Rebuilt bin/control-api and bin/admin-dashboard to match. Plans and summaries
are in docs/changes; README, API, USAGE, DASHBOARD and DIAGRAMS are updated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
db73409e8f
commit
864208238f
34 files changed
+1570
-72
No files matched your search
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -350,6 +351,33 @@ func TestMigration0009Indexes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRegistryLevelsQueryUsesIndex guards against a full scan of checks: both
|
||||
// the per-address MAX(cycle_id) and the join back must go through
|
||||
// idx_checks_registry_cycle.
|
||||
func TestRegistryLevelsQueryUsesIndex(t *testing.T) {
|
||||
d, ctx := newTestDB(t)
|
||||
rows, err := d.QueryContext(ctx, "EXPLAIN QUERY PLAN "+registryLevelsQuery(3), 1, 2, 3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var plan string
|
||||
for rows.Next() {
|
||||
var id, parent, unused int
|
||||
var detail string
|
||||
if err := rows.Scan(&id, &parent, &unused, &detail); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
plan += detail + "\n"
|
||||
if strings.HasPrefix(detail, "SCAN") && strings.Contains(detail, "checks") {
|
||||
t.Errorf("full scan of checks in plan:\n%s", plan)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(plan, "idx_checks_registry_cycle") {
|
||||
t.Errorf("expected idx_checks_registry_cycle in plan:\n%s", plan)
|
||||
}
|
||||
}
|
||||
|
||||
// TestScaleSmoke6440 pushes a realistic project size through the hot paths
|
||||
// with a loose time bound: the point is the absence of O(n^2) / N+1 work, not
|
||||
// a benchmark.
|
||||
@@ -369,11 +397,36 @@ func TestScaleSmoke6440(t *testing.T) {
|
||||
}
|
||||
submitDur := time.Since(start)
|
||||
|
||||
// A realistic check set for the addresses of the registry page below:
|
||||
// 12 egress and 18 ingress checks each.
|
||||
for _, addr := range addrs[3000:3100] {
|
||||
ip, err := d.GetIPByAddress(ctx, addr)
|
||||
if err != nil {
|
||||
t.Fatalf("get %s: %v", addr, err)
|
||||
}
|
||||
for i := 0; i < 30; i++ {
|
||||
source, checkType := SourceEgress, []string{"https", "icmp"}[i%2]
|
||||
if i >= 12 {
|
||||
source, checkType = InboundSource(i%3+1), fmt.Sprintf("tcp-%d", 20+i)
|
||||
}
|
||||
if err := d.UpsertCheck(ctx, Check{
|
||||
IPID: ip.ID, IPAddress: addr, AttemptNumber: ip.AttemptNumber,
|
||||
Source: source, CheckType: checkType, Target: fmt.Sprintf("t%d", i),
|
||||
Success: i%5 != 0, CheckedAt: Now(),
|
||||
}); err != nil {
|
||||
t.Fatalf("upsert check: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start = time.Now()
|
||||
page, total, err := d.ListRegistryPage(ctx, RegistryFilter{}, 100, 3000)
|
||||
if err != nil || total != 6440 || len(page) != 100 {
|
||||
t.Fatalf("registry page: total=%d len=%d err=%v", total, len(page), err)
|
||||
}
|
||||
if e, i := page[0].Egress.Total, page[0].Ingress.Total; e != 12 || i != 18 {
|
||||
t.Fatalf("levels of the first page row: egress=%d ingress=%d", e, i)
|
||||
}
|
||||
if _, total, err = d.ListRegistryPage(ctx, RegistryFilter{LastResult: ResultPass}, 100, 0); err != nil || total != 0 {
|
||||
t.Fatalf("registry last_result filter: total=%d err=%v", total, err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user