Skip to content

refactor(server): split bootstrap.rs into the boot/ tree - #4031

Merged
hubcio merged 3 commits into
masterfrom
server-ng-pr2-boot-tree
Sep 2, 2026
Merged

refactor(server): split bootstrap.rs into the boot/ tree#4031
hubcio merged 3 commits into
masterfrom
server-ng-pr2-boot-tree

Conversation

@hubcio

@hubcio hubcio commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

bootstrap.rs had grown to 5.1k lines holding every boot concern at
once: config and credential loading, listener start-up, partition
recovery, shard thread handles, the metadata handoff and the
cluster topology. None of it could be read or tested in isolation.

Move each concern into its own boot/ module and keep the shard_main
narrative, with its ordering invariants, whole in boot/mod.rs. Fold
three duplications the split exposed. The five-channel stop
fan-out was copied between the listener-failure and normal
shutdown paths; StopSignals owns it now. The rustls crypto provider
was installed at four sites; bootstrap installs it once before any
shard thread exists. The cluster roster carried the config-declared
ports while the HTTP state patched in the bound one, so the two
disagreed under port-0 binds; shard 0 now publishes the bound ports
into the one roster, and current_config.toml gains the bound HTTP
address so a harness can discover an ephemeral HTTP port like the
other transports.

New integration tests pin the iggy-view header on success, denial,
ping and follower relay, and bound-port discovery under port-0
binds.

@github-actions github-actions Bot added the S-waiting-on-review PR is waiting on a reviewer label Sep 1, 2026
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.29353% with 564 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.98%. Comparing base (bbfad59) to head (4bdf28d).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
core/server/src/boot/credentials.rs 55.59% 128 Missing and 3 partials ⚠️
core/server/src/boot/recovery.rs 83.33% 96 Missing and 13 partials ⚠️
core/server/src/boot/threads.rs 71.62% 93 Missing and 8 partials ⚠️
core/server/src/boot/listeners.rs 77.21% 72 Missing and 18 partials ⚠️
core/server/src/boot/mod.rs 86.85% 56 Missing and 15 partials ⚠️
core/server/src/boot/topology.rs 92.16% 22 Missing and 15 partials ⚠️
core/server/src/boot/handoff.rs 90.05% 14 Missing and 4 partials ⚠️
core/server/src/http.rs 90.90% 3 Missing and 1 partial ⚠️
core/server/src/http/forward.rs 66.66% 2 Missing ⚠️
core/server/src/config_writer.rs 96.15% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #4031      +/-   ##
============================================
+ Coverage     84.97%   84.98%   +0.01%     
  Complexity     1402     1402              
============================================
  Files          1230     1236       +6     
  Lines        181408   181465      +57     
  Branches     147703   147761      +58     
============================================
+ Hits         154157   154224      +67     
+ Misses        23199    23164      -35     
- Partials       4052     4077      +25     
Components Coverage Δ
Rust Core 86.02% <81.29%> (+<0.01%) ⬆️
Java SDK 67.29% <ø> (ø)
C# SDK 75.46% <ø> (ø)
Python SDK 90.06% <ø> (ø)
PHP SDK 85.65% <ø> (ø)
Node SDK 94.50% <ø> (+0.11%) ⬆️
Go SDK 69.35% <ø> (-0.02%) ⬇️
Files with missing lines Coverage Δ
core/metadata/src/impls/metadata.rs 88.05% <ø> (+0.03%) ⬆️
core/server/src/cluster_meta.rs 99.20% <100.00%> (+0.13%) ⬆️
core/server/src/dispatch/mod.rs 92.27% <100.00%> (+<0.01%) ⬆️
core/server/src/http/error.rs 87.00% <100.00%> (+0.03%) ⬆️
core/server/src/http/state.rs 88.42% <ø> (ø)
core/server/src/http/tls.rs 84.74% <100.00%> (ø)
core/server/src/main.rs 66.66% <ø> (ø)
core/server/src/partition_helpers.rs 76.04% <ø> (ø)
core/server/src/server_error.rs 37.25% <ø> (ø)
core/server/src/shell.rs 90.74% <ø> (ø)
... and 11 more

... and 38 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

spetz
spetz previously approved these changes Sep 2, 2026
bootstrap.rs had grown to 5.1k lines holding every boot concern at
once: config and credential loading, listener start-up, partition
recovery, shard thread handles, the metadata handoff and the
cluster topology. None of it could be read or tested in isolation.

Move each concern into its own boot/ module and keep the shard_main
narrative, with its ordering invariants, whole in boot/mod.rs. Fold
three duplications the split exposed. The five-channel stop
fan-out was copied between the listener-failure and normal
shutdown paths; StopSignals owns it now. The rustls crypto provider
was installed at four server-crate sites; bootstrap installs it
once before any shard thread exists, and the idempotent installs
message_bus keeps for its own embedders become no-ops. The cluster
roster carried the config-declared ports while the HTTP state
patched in the bound one, so the two disagreed under port-0 binds;
shard 0 now publishes the bound ports into the one roster, and
current_config.toml gains the bound HTTP address so a harness can
discover an ephemeral HTTP port like the other transports.

Two boot-order details change with the move. HTTP binds before the
replica and client listeners so its port is known when the roster
and current_config.toml are written; an http.address colliding
with tcp.address therefore fails as a TCP bind error. The
replica_io listener path returns an error instead of silently
returning when reached off shard 0, a case its only caller gates.

The harness readiness gate treats a transport section missing its
enabled or address key as a dump still being written and retries,
since the dump lands as one truncate plus one write.

New integration tests pin the iggy-view header on success, denial,
ping, follower redirect and follower relay (three nodes, the
smallest cluster that keeps a quorum through a leader change, with
the follower's header pinned to the view the primary stamps), and
bound-port discovery under port-0 binds.
A second review pass over the boot/ split found no behavior
defects but five loose ends worth closing before merge.

load_partition was tree-visible with a single in-file caller, and
the build_cluster_roster doc still named the roster's self fields
by a wildcard. The harness readiness check paired transport labels
and address slots by position across two separately ordered
arrays, so reordering either would mislabel a mismatch; one array
of triples pairs them explicitly. The orchestrator and the port
reserver each hand-rolled the loopback address mapping that
IpAddrKind::loopback already centralizes. The three-node iggy-view
tests sampled the primary's view only after the follower answered,
so a view change in between would fail a correct follower; they
now bracket the request and accept the range.
Comment thread core/server/src/boot/listeners.rs
Hoisting the HTTP bind above the replica start, so the roster and
current_config.toml learn its port, left the socket listening with
no serve loop behind it for the whole peer dial. That dial has no
timeout: a peer dropping SYNs holds it for the kernel retry budget
(about 127s at tcp_syn_retries=6), and since the kernel completes
handshakes into the backlog, a TCP readiness probe passes and routes
traffic to a node that answers nothing. On master the port was still
unbound at that point and probes got ECONNREFUSED.

Split http::bind into prepare, which validates [http.*] and builds
the serve-loop inputs before any listener accepts, and
PreparedHttp::bind, which opens the socket right before the port is
published. The roster and the config dump still learn the port, and
only the publish and the dump write sit between bind and serve.
@hubcio
hubcio merged commit 38d58ca into master Sep 2, 2026
98 checks passed
@hubcio
hubcio deleted the server-ng-pr2-boot-tree branch September 2, 2026 08:56
@github-actions github-actions Bot removed the S-waiting-on-review PR is waiting on a reviewer label Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants