From 6056a518b8c542713d85134e0b6928718829ad79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Sat, 20 Jun 2026 23:52:33 +0800 Subject: [PATCH] refactor: streamline embedded startup result shell (#3667) --- docs/architecture/migration-progress.md | 55 +++++++++++++++++++++---- rustfs/src/embedded.rs | 24 ++++++----- rustfs/src/startup_embedded.rs | 6 ++- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index f28acc39c..5d3312fe3 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,15 +5,16 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block ## Current Context - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) -- Branch: `overtrue/arch-embedded-startup-identity-flow` -- Baseline: completed `R-044/R-045`. -- Stacked on: embedded builder shell slice. +- Branch: `overtrue/arch-embedded-startup-result-shell` +- Baseline: completed `R-046/R-047`. +- Stacked on: embedded startup identity slice. - PR type for this branch: `pure-move` - Runtime behavior changes: none. -- Rust code changes: hide embedded startup argument fields behind crate-only - setters and return public server identity from the startup result. +- Rust code changes: consume embedded builder startup arguments directly and + keep startup-result-to-public-handle mapping plus ready logging at clear + ownership boundaries. - CI/script changes: none. -- Docs changes: record the embedded startup identity slices. +- Docs changes: record the embedded startup result shell slices. ## Phase 0 Tasks @@ -2388,6 +2389,28 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block check, migration/layer guards, formatting, diff hygiene, Rust risk scan, branch freshness check, pre-commit quality gate, and three-expert review. +- [x] `R-048` Consume embedded builder startup arguments directly. + - Do: make public embedded build consume the builder state and pass startup + arguments directly into the crate-only startup owner. + - Acceptance: fluent builder behavior, defaults, configured credentials, + region, volume ordering, and public build signature remain unchanged. + - Must preserve: startup argument ownership, public builder method chaining, + startup error mapping, and no public API signature changes. + - Verification: focused startup-embedded and embedded checks, RustFS lib + check, migration/layer guards, formatting, diff hygiene, Rust risk scan, + branch freshness check, pre-commit quality gate, and three-expert review. + +- [x] `R-049` Keep embedded ready logging with startup completion. + - Do: move embedded ready logging to the startup owner once readiness has + been published and before the startup result is returned. + - Acceptance: ready log endpoint text and endpoint normalization remain the + same while the public builder only converts the startup result to a handle. + - Must preserve: readiness publication order, endpoint address normalization, + shutdown handle ownership, and no public API signature changes. + - Verification: focused startup-embedded and embedded checks, RustFS lib + check, migration/layer guards, formatting, diff hygiene, Rust risk scan, + branch freshness check, pre-commit quality gate, and three-expert review. + - [x] `E-001/E-SET-001` Add ECStore layout skeleton and set-layout boundary. - Do: create the ECStore internal layout ownership buckets and pin static set layout versus runtime `Sets`/`SetDisks` orchestration boundaries before any @@ -2631,20 +2654,34 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block ## Next PRs 1. `pure-move`: continue pruning residual embedded handle/startup-only - boundaries after the embedded startup identity slice lands. + boundaries after the embedded startup result shell slice lands. ## Pre-Push Review Log | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | R-046 and R-047 hide startup argument mutation behind crate-only methods and move public server identity assembly into the startup result without widening the public API. | -| Migration preservation | passed | Builder setter semantics, public server identity accessors, endpoint handling, startup error mapping, and shutdown ownership stay unchanged. | +| Quality/architecture | passed | R-048 and R-049 keep the public embedded builder as a shell over the startup owner and localize ready logging with startup completion. | +| Migration preservation | passed | Builder chaining, defaults, configured identity, endpoint normalization, readiness publication order, and shutdown ownership stay unchanged. | | Testing/verification | passed | Focused startup-embedded/embedded checks, RustFS lib check, architecture/layer/unsafe guards, formatting, diff hygiene, Rust risk scan, and pre-commit gate passed. | ## Verification Notes Passed before push: +- Issue #660 R-048/R-049 current slice: + - `cargo test -p rustfs --lib startup_embedded -- --nocapture`: passed. + - `cargo test -p rustfs --lib embedded -- --nocapture`: passed. + - `cargo check -p rustfs --lib`: passed. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - `./scripts/check_layer_dependencies.sh`: passed. + - `./scripts/check_unsafe_code_allowances.sh`: passed. + - Rust risk scan on changed Rust files: passed; no risky-token matches were + present in changed Rust files. + - `make pre-commit`: passed; nextest ran 6329 tests with 6329 passed and + 111 skipped, and doctests passed. + - Issue #660 R-046/R-047 current slice: - `cargo test -p rustfs --lib startup_embedded -- --nocapture`: passed. - `cargo test -p rustfs --lib embedded -- --nocapture`: passed. diff --git a/rustfs/src/embedded.rs b/rustfs/src/embedded.rs index 952261963..bb2599c9b 100644 --- a/rustfs/src/embedded.rs +++ b/rustfs/src/embedded.rs @@ -47,8 +47,8 @@ //! start a second server will return an error. use crate::server::ShutdownHandle; -use crate::startup_embedded::{EmbeddedStartupArgs, EmbeddedStartupError, run_embedded_startup}; -use crate::startup_lifecycle::{embedded_endpoint_address, log_embedded_server_ready}; +use crate::startup_embedded::{EmbeddedStartedServer, EmbeddedStartupArgs, EmbeddedStartupError, run_embedded_startup}; +use crate::startup_lifecycle::embedded_endpoint_address; use crate::startup_server::find_embedded_available_port; use crate::startup_shutdown::{run_embedded_server_drop_cleanup, run_embedded_server_shutdown}; use std::net::SocketAddr; @@ -207,14 +207,20 @@ impl RustFSServerBuilder { /// Returns [`ServerError::AlreadyStarted`] if another server is already /// running in this process, or if another startup attempt has already /// entered irreversible global initialization. - pub async fn build(mut self) -> Result { + pub async fn build(self) -> Result { self.do_build().await } - async fn do_build(&mut self) -> Result { - let started = run_embedded_startup(self.startup_args.clone()).await?; + async fn do_build(self) -> Result { + let started = run_embedded_startup(self.startup_args).await?; - let server = RustFSServer { + Ok(started.into()) + } +} + +impl From for RustFSServer { + fn from(started: EmbeddedStartedServer) -> Self { + Self { address: started.bound_addr, access_key: started.access_key, secret_key: started.secret_key, @@ -222,11 +228,7 @@ impl RustFSServerBuilder { shutdown_handle: Some(started.shutdown_handle), cancel_token: started.cancel_token, temp_dir: started.temp_dir, - }; - - log_embedded_server_ready(server.endpoint_address()); - - Ok(server) + } } } diff --git a/rustfs/src/startup_embedded.rs b/rustfs/src/startup_embedded.rs index 148122da1..c8f891370 100644 --- a/rustfs/src/startup_embedded.rs +++ b/rustfs/src/startup_embedded.rs @@ -14,7 +14,9 @@ use crate::{ server::ShutdownHandle, - startup_lifecycle::{EmbeddedStartupGuard, publish_embedded_startup_ready}, + startup_lifecycle::{ + EmbeddedStartupGuard, embedded_endpoint_address, log_embedded_server_ready, publish_embedded_startup_ready, + }, startup_runtime_hooks::init_embedded_runtime_hooks, startup_server::{ EmbeddedStartupConfig, init_embedded_startup_listen_context, prepare_embedded_startup_config, start_embedded_http_server, @@ -170,6 +172,8 @@ pub(crate) async fn run_embedded_startup(args: EmbeddedStartupArgs) -> Result