Skip to main content

StoreConfig

Struct StoreConfig 

Source
pub struct StoreConfig {
    pub backend: StoreBackend,
    pub owned_shards: Vec<usize>,
    pub data_dir: Option<String>,
    pub shard_count: usize,
    pub cluster: Option<ClusterConfig>,
    pub node_cache_budget: Option<NodeCacheBudget>,
    pub lock_acquisition_patience_ms: Option<u64>,
    pub lock_acquisition_retry_cadence_ms: Option<u64>,
    /* private fields */
}
Expand description

Event-store backend configuration from [store].

Fields§

§backend: StoreBackend

Selected backing store implementation.

§owned_shards: Vec<usize>

Static distribution-shard assignment for this node (multi-shard active-active). When empty (the default) the node owns ALL shards — the single-node default, byte-identical to today. When set, the engine boot path scopes recovery and enumeration to exactly these shards. The single-shard memory backend ignores the assignment; it is meaningful only for a sharded backend. No election is performed: assignment is static config.

§data_dir: Option<String>

Filesystem data directory for the haematite backend. Required when backend = haematite; ignored by every other backend. The directory is opened if it already holds a haematite database, otherwise created.

§shard_count: usize

Number of haematite shards to create on a fresh database. Defaults to 64.

This is an IMMUTABLE virtual-shard count: nodes own shard ranges and routing is BLAKE3(key) % shard_count with no reshard path, so a single-node deployment can later grow into a cluster WITHOUT a data migration — but only up to shard_count nodes, and the value is fixed at create.

The default was briefly 4096 on the premise that lazy shard-actor materialization (haematite >= 0.4.0) made a high count ~free. That premise fails in practice (#187): aion-server’s boot restores packages/routes/namespaces via full-prefix scans, which materialize EVERY shard, and haematite 0.4.0 then fans each commit out to every materialized shard with an unconditional fsync — ~2 fsyncs x 4096 per logical commit — blowing the 5s shard-actor timeout and bricking deploy/start/timers/outbox on a fresh server. Re-raise only after haematite makes commit O(dirty shards) and the scaffold e2es pass at the new default. Set explicitly (config or AION_STORE_SHARD_COUNT) to override. Ignored by every other backend, and ignored when opening an existing haematite database (the on-disk shard count wins).

§cluster: Option<ClusterConfig>

Optional distributed-cluster membership for the haematite backend (SS-2).

Absent (the default) selects the SINGLE-NODE haematite path, byte-identical to today: no endpoint is bound, no shard is elected, the store owns everything locally. Present selects the DISTRIBUTED path: the boot path binds a replication endpoint, builds a quorum membership from members + peers, and the engine boot path elects (acquire_shard_and_serve) this node’s owned_shards before recovery. Ignored by every non-haematite backend.

§node_cache_budget: Option<NodeCacheBudget>

The byte ceiling the haematite node caches may hold. Required; no default — the haematite boot path refuses to start without it. Ignored by every other backend (only haematite has a node cache), which is why it is required where it is USED rather than at parse time: a memory deployment is not asked to rule on a cache it does not have.

A node is not a fixed-size thing — under byte-aware chunking a leaf reaches the ~96KB class — so a cache bounded only by max_entries carries a standing footprint of entries x (whatever a node weighs), unbounded in bytes by construction. This is the missing bound, and haematite 0.8.2 refuses a DatabaseConfig that does not carry it.

Deserialized through haematite’s own wire shape, so there is exactly one parser for this value estate-wide:

[store]
node_cache_budget = { bytes = 1073741824 }  # 1 GiB
# or, the pre-budget behaviour said out loud:
node_cache_budget = "unlimited"

Absence refuses STORE_NODE_CACHE_BUDGET_REQUIRED for an embedder-built config; for a config FILE the boot-side heal (config::heal) inserts the declared default ("unlimited") on a haematite boot instead of refusing, preserving the previous file beside it. A zero byte count is refused by haematite at parse time (a zero ceiling admits nothing, which is “disable the cache” and must be spelled differently) — the heal never touches a present value.

§lock_acquisition_patience_ms: Option<u64>

RETIRED (2026-08-24) and ignored: boot now waits indefinitely for the data-directory writer lock — a kernel-released flock whose holder is either live mid-handover or already gone, so a patience ceiling only converted slow handovers into refused boots. Kept so a configuration that still carries the key stays LEGAL (warned, never refused) and existing estates boot unchanged.

§lock_acquisition_retry_cadence_ms: Option<u64>

RETIRED (2026-08-24) and ignored, with lock_acquisition_patience_ms: the wait’s internal probe cadence is an implementation constant, not configuration. Kept only so the key stays legal in existing files.

Trait Implementations§

Source§

impl Clone for StoreConfig

Source§

fn clone(&self) -> StoreConfig

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for StoreConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for StoreConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for StoreConfig

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoMaybeUndefined<T> for T

Source§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
Source§

impl<T> IntoOption<T> for T

Source§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more