diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 05430306..4f940c80 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -165,6 +165,15 @@ impl StorageConfig { pub fn as_trait(&self) -> &(dyn extenddb_storage::config::StorageConfig + 'static) { &*self.config } + + /// Set the node's instance identifier on the underlying config. + /// + /// Backends that need a per-node identity read this via + /// [`extenddb_storage::config::StorageConfig::instance_id`]. Call this + /// before passing the config to the backend factory. + pub fn set_instance_id(&mut self, instance_id: &str) { + self.config.set_instance_id(instance_id); + } } impl<'de> serde::Deserialize<'de> for StorageConfig { diff --git a/crates/server/src/serve.rs b/crates/server/src/serve.rs index 6d7c9da0..802be8fc 100644 --- a/crates/server/src/serve.rs +++ b/crates/server/src/serve.rs @@ -191,7 +191,7 @@ pub async fn serve(params: ServeParams) -> anyhow::Result<()> { /// any error path. async fn serve_inner(params: ServeParams, port: u16) -> anyhow::Result<()> { let ServeParams { - app_config, + mut app_config, listener: std_listener, pid_file, log_target, @@ -287,7 +287,15 @@ async fn serve_inner(params: ServeParams, port: u16) -> anyhow::Result<()> { // to bootstrap an uninitialized catalog at serve time (zero-config use). let mut component_options = extenddb_storage::server_components::ServerComponentsOptions::default(); + component_options.bootstrap_if_uninitialized = dev_mode; + + // Wire the node's own bind address as the instance ID so each ExtendDB node + // has a distinct node ID (to support logical clocks for sequences, etc.). + app_config + .storage + .set_instance_id(&format!("{}:{}", app_config.server.bind_addr, port)); + let components = extenddb_storage::create_server_components( app_config.storage.as_trait(), &app_config.server.region, diff --git a/crates/storage/src/config.rs b/crates/storage/src/config.rs index 2101bc5f..3bdb1204 100644 --- a/crates/storage/src/config.rs +++ b/crates/storage/src/config.rs @@ -68,6 +68,17 @@ pub trait StorageConfig: Send + Sync + std::fmt::Debug { fn as_any(&self) -> &dyn std::any::Any where Self: 'static; + + /// Set a per-node instance identifier used to derive backend-specific + /// node identities (e.g. HLC node IDs for stream sequence numbers). + /// Backends that do not need a node identity may ignore this. + fn set_instance_id(&mut self, _instance_id: &str) {} + + /// Return the instance identifier previously set via [`set_instance_id`], + /// if any. + fn instance_id(&self) -> Option<&str> { + None + } } impl Clone for Box {