Files
meshcore-analyzer/cmd/server
MeshCore Bot dbadef3e2f refactor(db): move all server writes to ingestor; server truly read-only (#1283)
Eliminates the SQLITE_BUSY VACUUM bug from #1283 by making cmd/server
truly read-only. The bug surfaced when supervisord launched both
ingestor + server in one container: the ingestor took the write lock for
INSERTs, then the server's VACUUM-on-startup immediately failed with
SQLITE_BUSY. Same race latently affected three other server-side writes.

Four write operations moved out of cmd/server/:

1. VACUUM / auto_vacuum migration (cmd/server/vacuum.go, entire file)
   → cmd/ingestor/db.go Store.CheckAutoVacuum (already existed;
     ingestor runs it BEFORE the MQTT subscriber starts so there is
     no contention with concurrent writes).

2. PruneOldPackets (DELETE FROM transmissions)
   cmd/server/db.go → cmd/ingestor/maintenance.go (new file,
     Store.PruneOldPackets) + main.go scheduler.

3. PruneOldMetrics (DELETE FROM observer_metrics)
   cmd/server/db.go → cmd/ingestor/db.go Store.PruneOldMetrics
     (already existed).

4. RemoveStaleObservers (UPDATE observers SET inactive = 1)
   cmd/server/db.go → cmd/ingestor/db.go Store.RemoveStaleObservers
     (already existed).

Server-side changes:
- vacuum.go deleted; checkAutoVacuum / runIncrementalVacuum gone.
- cmd/server/db.go: PruneOldPackets, PruneOldMetrics, RemoveStaleObservers
  deleted.
- cmd/server/main.go: packet/metrics/observer prune schedulers removed;
  the neighbor-edge prune scheduler (PruneNeighborEdges) is intentionally
  left in place — outside scope of #1283, tracked separately.
- routes.go + openapi.go: /api/admin/prune endpoint removed (prune is
  scheduled by the ingestor now; operators restart the ingestor for an
  ad-hoc pass).

Ingestor changes:
- New cmd/ingestor/maintenance.go with Store.PruneOldPackets.
- cmd/ingestor/config.go gains RetentionConfig.PacketDays and
  Config.PacketDaysOrZero().
- cmd/ingestor/main.go runs PruneOldPackets at startup (if
  packetDays > 0) and on a 24h ticker.

Docs:
- AGENTS.md: documents the read/write separation invariant.
- config.example.json: notes that retention + vacuumOnStartup are
  consumed by the ingestor.

TDD:
- Red: bb1d749a — invariant tests + Store.PruneOldPackets stub.
- Green: this commit — real implementation + server-side removals.

Note: cachedRW() still has three out-of-scope callers in cmd/server
(neighbor_persist.go, ensure_indexes.go, from_pubkey_migration.go).
Those are pre-existing write paths not covered by issue #1283 and are
left untouched per the issue scope. Future work can relocate them
under the same invariant.
2026-05-19 06:31:17 +00:00
..