MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / join

Function join

nodedb-cluster/src/bootstrap/join.rs:74–139  ·  view source on GitHub ↗

Join an existing cluster by contacting seed nodes. The loop has two layers: - **Outer**: retry passes with exponential backoff per `config.join_retry`. Handles the "bootstrapper not up yet" startup race. - **Inner**: walk the seed list plus any leader-redirect hops for this attempt. A successful `JoinResponse` short-circuits the whole function; failures on one candidate fall through to the next.

(
    config: &ClusterConfig,
    catalog: &ClusterCatalog,
    transport: &NexarTransport,
    lifecycle: &ClusterLifecycleTracker,
)

Source from the content-addressed store, hash-verified

72/// whole function; failures on one candidate fall through to the
73/// next.
74pub(super) async fn join(
75 config: &ClusterConfig,
76 catalog: &ClusterCatalog,
77 transport: &NexarTransport,
78 lifecycle: &ClusterLifecycleTracker,
79) -> Result<ClusterState> {
80 info!(
81 node_id = config.node_id,
82 seeds = ?config.seed_nodes,
83 "joining existing cluster"
84 );
85
86 if config.seed_nodes.is_empty() {
87 let err = ClusterError::Transport {
88 detail: "no seed nodes configured".into(),
89 };
90 lifecycle.to_failed(err.to_string());
91 return Err(err);
92 }
93
94 let req_template = JoinRequest {
95 node_id: config.node_id,
96 listen_addr: config.listen_addr.to_string(),
97 wire_version: crate::topology::CLUSTER_WIRE_FORMAT_VERSION,
98 spiffe_id: None,
99 spki_pin: transport.local_spki_pin().map(|arr| arr.to_vec()),
100 };
101
102 let policy = config.join_retry;
103 let mut last_err: Option<ClusterError> = None;
104
105 for attempt in 0..policy.max_attempts {
106 lifecycle.to_joining(attempt);
107
108 let delay = policy.backoff_for(attempt);
109 if !delay.is_zero() {
110 debug!(
111 node_id = config.node_id,
112 attempt,
113 delay_ms = delay.as_millis() as u64,
114 "backing off before next join attempt"
115 );
116 tokio::time::sleep(delay).await;
117 }
118
119 match try_join_once(config, catalog, transport, &req_template).await {
120 Ok(state) => return Ok(state),
121 Err(e) => {
122 warn!(
123 node_id = config.node_id,
124 attempt,
125 error = %e,
126 "join attempt failed; will retry"
127 );
128 last_err = Some(e);
129 }
130 }
131 }

Callers 2

start_clusterFunction · 0.85
full_bootstrap_join_flowFunction · 0.85

Calls 9

try_join_onceFunction · 0.85
to_failedMethod · 0.80
to_stringMethod · 0.80
local_spki_pinMethod · 0.80
to_joiningMethod · 0.80
backoff_forMethod · 0.80
is_zeroMethod · 0.80
is_emptyMethod · 0.45
to_vecMethod · 0.45

Tested by

no test coverage detected