Documentation
¶
Overview ¶
Package replicator gives Base's per-tenant SQLite substrate continuous streaming replication and point-in-time restore via hanzoai/replicate — the HA / resilience layer (Pillar 2): a pod dying or rescheduling restores each tenant DB from its replica (bounded RPO, no data loss).
One at-rest boundary — encryption lives in the storage client ¶
Encryption is NOT applied at replicate's LTX layer. In production the replica client is a vfs-backed client that PQ-encrypts every block with the tenant's age key (store.TenantKey) — the SAME key the whole-file path uses. So there is exactly one at-rest boundary (luxfi/age, ML-KEM-768 + X25519), one key per tenant, across the whole-file, block, and replica-stream paths, with no double-encryption.
(replicate v0.8.0's built-in age — Replica.AgeRecipients — is deliberately unused: it encrypts the LTX stream BEFORE the file/s3 client peeks the LTX header for a timestamp, so those clients reject the ciphertext. Keeping encryption in the storage client is both the correct single-boundary design and the working one.)
Lifecycle per tenant DB:
Restore(...) pull the DB from its replica into a fresh pod (failover / hydrate) Open(...) start tailing the WAL to the replica Handle.Sync force a checkpoint + push (driven by the store's checkpoint) Handle.Close stop streaming (on evict / shutdown)
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle is a running replication of one tenant DB. Stop it on evict/close.
func Open ¶
func Open(localPath string, client replicate.ReplicaClient) (*Handle, error)
Open starts replication of the SQLite DB at localPath to client. The caller keeps writing through its own connection; replicate tails the WAL on Sync. client owns at-rest encryption (vfs-backed, per-tenant, in production).