Store (Key-Value)
Store (Key-Value)
Section titled “Store (Key-Value)”Key-value stores with TTL support: in-memory, SQL-backed, and cluster-replicated (Raft and CRDT).
Entry Kinds
Section titled “Entry Kinds”| Kind | Description |
|---|---|
store.memory | In-memory store with automatic cleanup |
store.sql | SQL-backed store with persistence |
store.kv.raft | Cluster-replicated, strongly-consistent KV on the shared Raft |
store.kv.crdt | Cluster-replicated, eventually-consistent KV over gossip (CRDT) |
Memory Store
Section titled “Memory Store”- name: sessions kind: store.memory max_size: 10000 cleanup_interval: "5m" lifecycle: auto_start: true| Field | Type | Default | Description |
|---|---|---|---|
max_size | int | 10000 | Maximum entries; 0 is replaced with the default (10000) |
cleanup_interval | duration | 5m | Expired entry cleanup interval |
When max_size is reached, new entries are rejected. Data is lost on restart.
SQL Store
Section titled “SQL Store”- name: cache kind: store.sql database: app:postgres table_name: kv_store cleanup_interval: "10m" lifecycle: auto_start: true| Field | Type | Default | Description |
|---|---|---|---|
database | reference | required | Database entry reference |
table_name | string | required | Table name for storage |
id_column_name | string | key | Column for keys |
payload_column_name | string | value | Column for values |
expire_column_name | string | expires_at | Column for expiration |
cleanup_interval | duration | 0 | Expired entry cleanup interval |
Column names are validated against SQL injection. Create the table before use:
CREATE TABLE kv_store ( key VARCHAR(255) PRIMARY KEY, value BYTEA NOT NULL, expires_at BIGINT);
CREATE INDEX idx_expires_at ON kv_store(expires_at) WHERE expires_at IS NOT NULL;Cluster KV Stores
Section titled “Cluster KV Stores”store.kv.raft and store.kv.crdt replicate key-value data across cluster nodes. Both require clustering to be enabled and reuse the same Store Module Lua API. Each entry is a namespaced view into one node-wide engine; namespace isolates this entry’s keys and must match ^[a-z][a-z0-9._-]*$ (it may not start with _).
Raft (strong consistency)
Section titled “Raft (strong consistency)”- name: deployments kind: store.kv.raft namespace: deploy| Field | Type | Required | Description |
|---|---|---|---|
namespace | string | Yes | Key namespace in the shared engine |
Writes are proposed through the shared Raft (followers forward to the leader); reads are linearizable. Conditional writes (put with only_if_absent/if_version) are supported. Raft state is fs-durable by default under cluster.raft.data_dir (default ~/.wippy/store); see Configuration.
CRDT (eventual consistency)
Section titled “CRDT (eventual consistency)”- name: sessions kind: store.kv.crdt namespace: sess durable: false| Field | Type | Required | Default | Description |
|---|---|---|---|---|
namespace | string | Yes | - | Key namespace |
durable | bool | No | false | Persist fs snapshots so the namespace survives a full-cluster restart |
Writes mutate local state and disseminate over gossip; conflicting concurrent writes converge last-writer-wins. Reads are local. Conditional writes are not supported. With durable: false the store is in-memory and reconstructs from peers; with durable: true it snapshots to <data_dir>/_sys/kvcrdt.
data_dir is node-level (cluster.raft.data_dir), not per-entry. The shared Raft state and durable CRDT snapshots live under <data_dir>/_sys/.
TTL Behavior
Section titled “TTL Behavior”Both stores support time-to-live. Expired entries persist briefly until cleanup runs at cleanup_interval. Set to 0 to disable automatic cleanup.
Lua API
Section titled “Lua API”See Store Module for operations: get, set, has, delete, plus put, entry, list, and info for versioned and conditional access.
See Also
Section titled “See Also”- Store Module - Lua API reference
- Database - SQL backing for
store.sql