Skip to content

feat(sketch-db): Phase 2c — on-disk schema registry persistence - #24

Merged
zzylol merged 1 commit into
mainfrom
sketchdb/phase2c-schema-persist
Apr 17, 2026
Merged

zzylol merged 1 commit into
mainfrom
sketchdb/phase2c-schema-persist

Conversation

@zzylol

@zzylol zzylol commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • SchemaRegistry::load_or_new_from_config(path, &StreamingConfig) loads a JSON snapshot if present and reconciles against the live config. created_at_ms / retired_at_ms / expires_at_ms survive restarts.
  • Every reconcile() rewrites the file atomically (tmp + rename). I/O errors are logged but never block reconcile.
  • Corrupt or wrong-version files fall back to a fresh registry (forward progress over historical accuracy).
  • PrecomputeEngineConfig::schema_persist_path + --schema-persist-path CLI flag. Unset = memory-only, matching pre-2c behaviour.
  • PERSIST_FORMAT_VERSION = 1 on-disk tag so future incompatible changes refuse to load instead of silently corrupting the timeline.

Why

Phase 3a explicitly noted the timeline loses pre-restart history without on-disk persistence. This PR closes that gap — one of the smaller todos on the sketch-DB roadmap but required for the Phase 3b-2 user-visible behaviour to hold across deploys.

Test plan

  • 6 new tests: round-trip across simulated restart, first-run creates file, reconcile-on-load, corrupt-file fallback, unsupported-version rejection + rewrite, non-persistent path writes nothing.
  • 567 lib tests pass (up from 561).
  • clippy + fmt clean.

🤖 Generated with Claude Code

Closes the "timeline loses all pre-restart history" gap that Phase 3a
explicitly left open. After a restart the §7 schema timeline now
recovers the actual `created_at_ms` / `retired_at_ms` /
`expires_at_ms` of every known `agg_id` instead of silently
re-stamping every schema as "created right now".

## What's persisted

`SchemaRegistry::load_or_new_from_config(path, &StreamingConfig)`:
* If `path` does not exist: builds from the config and persists
  immediately — next restart has something to read.
* If `path` exists and parses: loads every schema verbatim
  (timestamps + `AggregationConfig`), then reconciles against the
  fresh config — new ids become Active, ids only on disk get retired
  if they weren't already.
* If `path` exists but is corrupt / wrong version: log a warning and
  fall back to fresh registry (preserves forward progress over
  historical accuracy).

Every `reconcile()` call atomically rewrites the file (write tmp +
rename). I/O errors are logged but never fail a reconcile — the
registry is always authoritative in memory.

## Wire-up

* New `AggSchema` derives `Serialize`/`Deserialize` (the underlying
  `AggregationConfig` already has them).
* `PrecomputeEngineConfig` gains `schema_persist_path:
  Option<PathBuf>` with `#[serde(default)]` for backward-compatible
  YAML config files.
* `--schema-persist-path <path>` CLI flag on the main binary; when
  unset, registry stays memory-only matching pre-Phase-2c behaviour.
* On-disk format is tagged with `PERSIST_FORMAT_VERSION = 1` so
  future incompatible schema evolution can refuse to load instead of
  silently corrupting the timeline.

## Test plan

- [x] 6 new tests in `stores::sketch_db::schema::tests`: round-trip
  preserves timestamps across simulated restart, first-run creates
  file, reconciles against fresh config, corrupt file falls back
  cleanly, unsupported version is rejected (fallback + rewrite),
  non-persistent path writes nothing.
- [x] 567 lib tests pass (up from 561).
- [x] clippy `--workspace --all-targets --tests -- -D warnings` clean.
- [x] `cargo fmt -- --check` clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol merged commit d6cf1fb into main Apr 17, 2026
@zzylol
zzylol deleted the sketchdb/phase2c-schema-persist branch April 17, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant