tidaldb/tidal-server/src/cluster/mod.rs
jx12n 225751d34d feat(m11): WAL-as-stream replication + perf floor (m11p1+m11p2)
m11p1 — decoupled ack/ship path: staged writes (seqno+WAL+relay-push,
microseconds) separate from group-commit fsync; ShipQueue batches+windows
outbound segments; receiver coalesces inbound chunks before applying.
Adds first tidaldb_cluster_* metrics.

m11p2 — leader WAL is now THE replicated log: fsynced batches feed a
bounded WalShipFeed and ship byte-identical to followers; WAL seqnos
survive restarts (relay-reset hazard gone). Item metadata and embeddings
journal kind-1/2 blob records on the same stream as signals; the m8p10
HTTP broadcast is deleted. StreamSegments catch-up is follower-pulled via
server-streaming RPC, triggered on gap detection, follower boot, and
leader heal nudge. Promote carries a stream baseline so peers skip
pre-stream history.
2026-06-11 09:10:06 -06:00

57 lines
2.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Cluster mode: multi-region tidalDB behind an HTTP surface.
//!
//! Two cluster modes share this module:
//!
//! * **Single-process** ([`ClusterState`], the m8p8 dev/demo default): every
//! region runs inside ONE process, wrapping [`SimulatedCluster`] with region
//! name ↔ [`RegionId`] mapping. Replication between regions still traverses a
//! real [`GrpcTransport`] on loopback (not in-process channels), but a crash
//! takes the whole "cluster" down — there is no process isolation.
//! * **Multi-process** ([`RegionClusterState`], the m8p10 mode, selected by
//! `--region`): this process owns exactly ONE region — one [`TidalDb`], one
//! [`GrpcTransport`] whose server binds this region's `grpc_addr` and whose
//! peers are every sibling region's real `grpc_addr` — and peers with sibling
//! processes over real gRPC. Process isolation is real; quorum-ack writes and
//! automatic failure detection are still future work.
//!
//! Both modes are gated behind the same explicit operator opt-in
//! ([`ensure_experimental_enabled`]).
//!
//! # Module layout (M0M10 review Maintainability-S follow-up)
//!
//! The original single 1379-line `cluster.rs` carried four loosely-coupled
//! concerns; it was split (behavior-neutral) into:
//!
//! * [`topology`] — `TopologySpec` / `RegionSpec` / `load_topology` / validation
//! * [`transport`] — single-process self-loop gRPC transport wiring
//! * [`state`] — [`ClusterState`] (single-process) + the experimental gate
//! * [`routes`] — the single-process router + handlers
//! * [`node`] — [`RegionClusterState`] (multi-process) + its router/handlers
//!
//! [`GrpcTransport`]: tidal_net::GrpcTransport
//! [`RegionId`]: tidaldb::replication::shard::RegionId
//! [`SimulatedCluster`]: tidaldb::testing::SimulatedCluster
//! [`TidalDb`]: tidaldb::TidalDb
pub(crate) mod forward;
pub(crate) mod node;
pub(crate) mod routes;
mod state;
mod topology;
mod transport;
// ── Public API (preserved across the split) ─────────────────────────────────
pub use node::{RegionClusterState, build_region_router};
pub use routes::build_cluster_router;
pub use state::{ClusterMode, ClusterState, EXPERIMENTAL_CLUSTER_ENV, ensure_experimental_enabled};
pub use topology::{
GrpcTlsSpec, RegionSpec, ReplicationSpec, TimeoutsSpec, TopologySpec, WalSpec, load_topology,
validate_multiproc,
};
// The OpenAPI documents (`crate::openapi`) reach the handlers/DTOs through
// `cluster::routes::…` / `cluster::node::…` directly, so the
// `#[utoipa::path]`-generated `__path_*` types resolve in the module that
// defines them. `node` reaches `ClusterAppError` via `super::routes`.