mix orkestra.projection.es.rebuild (orkestra v0.2.0)

Copy Markdown View Source

Rebuilds an Elasticsearch projection by creating a new versioned index, replaying all events, atomically swapping the alias, and cleaning up the old index — without any search downtime.

Usage

mix orkestra.projection.es.rebuild MyApp.OrderESProjector

Options

  • --yes - Skip confirmation prompt (for scripting/CI).

Rebuild sequence

  1. Validate that the module is an ES projector (backend: :elasticsearch).
  2. Build a stream of Snap.Bulk.Action.Index structs by replaying all events from the EventStore through the projector's __handle_es__/3.
  3. Call Snap.Indexes.hotswap/5 which atomically creates a versioned index, bulk-loads the stream, refreshes, swaps the alias, and cleans up old indexes (keeping the 2 most recent).
  4. Pause the live GenServer via GenServer.call(pid, :pause_writes) to prevent race conditions during the alias swap window (RBLD-03).
  5. Reset the Postgres checkpoint so the GenServer replays from position 0.
  6. Resume the live GenServer via GenServer.call(pid, :resume_writes).

After resume, the GenServer resubscribes from position -1 (no checkpoint) and replays all events into the new index. Documents are idempotent (deterministic _id), so duplicate writes are safe.

Error handling

If hotswap/5 fails (e.g. bulk error, connection failure), the task exits with an error. The old index and alias remain untouched — no data loss. Re-running the task starts a fresh rebuild.