Spawn the default cluster subsystems sharing `raft_multi_raft` with the running [`crate::raft_loop::RaftLoop`]. Called after [`start_cluster`] has produced [`ClusterState`] and the host has handed `MultiRaft` over to the `RaftLoop`. The host passes `raft_multi_raft = raft_loop.multi_raft_handle()` here so subsystems use the same `Arc >` the loop owns — no double-ownership, no orph
(
config: &ClusterConfig,
topology: Arc<std::sync::RwLock<crate::topology::ClusterTopology>>,
routing: Arc<std::sync::RwLock<crate::routing::RoutingTable>>,
transport: Arc<NexarTranspo
| 181 | /// orderly shutdown so subsystems release their `MultiRaft` Arc |
| 182 | /// before the loop exits. |
| 183 | pub async fn start_cluster_subsystems( |
| 184 | config: &ClusterConfig, |
| 185 | topology: Arc<std::sync::RwLock<crate::topology::ClusterTopology>>, |
| 186 | routing: Arc<std::sync::RwLock<crate::routing::RoutingTable>>, |
| 187 | transport: Arc<NexarTransport>, |
| 188 | raft_multi_raft: Arc<std::sync::Mutex<crate::multi_raft::MultiRaft>>, |
| 189 | ) -> Result<RunningCluster> { |
| 190 | let health = ClusterHealth::new(); |
| 191 | let ctx = BootstrapCtx::new( |
| 192 | Arc::clone(&topology), |
| 193 | Arc::clone(&routing), |
| 194 | Arc::clone(&transport), |
| 195 | Arc::clone(&raft_multi_raft), |
| 196 | health, |
| 197 | ); |
| 198 | |
| 199 | let executor = Arc::new(MigrationExecutor::new( |
| 200 | Arc::clone(&raft_multi_raft), |
| 201 | Arc::clone(&routing), |
| 202 | Arc::clone(&topology), |
| 203 | Arc::clone(&transport), |
| 204 | )); |
| 205 | |
| 206 | let mut registry = SubsystemRegistry::new(); |
| 207 | register_default_subsystems(&mut registry, config, &ctx, executor)?; |
| 208 | |
| 209 | registry |
| 210 | .start_all(&ctx) |
| 211 | .await |
| 212 | .map_err(|e| crate::error::ClusterError::Storage { |
| 213 | detail: format!("subsystem start failed: {e}"), |
| 214 | }) |
| 215 | } |
no test coverage detected