From 9a3d5bd2a044a7f16c242bfc506ca6aa7c2d8379 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 09:15:00 +0800 Subject: [PATCH] refactor: reuse embedded lifecycle publication boundaries (#3642) --- docs/architecture/migration-progress.md | 54 +++++++++++++++---------- docs/architecture/runtime-lifecycle.md | 7 ++++ rustfs/src/embedded.rs | 16 ++------ rustfs/src/startup_lifecycle.rs | 25 +++++++++++- 4 files changed, 66 insertions(+), 36 deletions(-) diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index d55cbffd9..b6905cb8a 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,16 +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-runtime-service-reuse` -- Baseline: `origin/main` - (`131e9dc804a371b3384028da5797ca32a91ac493`). +- Branch: `overtrue/arch-embedded-lifecycle-publication-reuse` +- Baseline: `overtrue/arch-embedded-runtime-service-reuse` + (`00cf2509338ec6acdddc3b5fdf1a02dd52ed309a`). +- Stacked on: rustfs/rustfs#3641. - PR type for this branch: `pure-move` - Runtime behavior changes: none. -- Rust code changes: route embedded runtime services and shutdown cleanup - through startup service/shutdown helpers while preserving embedded-only fatal - and non-fatal behavior. +- Rust code changes: route embedded ready publication, global init-time + publication, and ready logging through startup lifecycle helpers. - CI/script changes: none. -- Docs changes: record the R-030 embedded runtime service reuse slice. +- Docs changes: record the R-031 embedded lifecycle publication reuse slice. ## Phase 0 Tasks @@ -2168,31 +2168,43 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block migration/layer guards, formatting, diff hygiene, Rust risk scan, branch freshness check, pre-commit quality gate, and three-expert review. +- [x] `R-031` Reuse lifecycle publication boundaries in embedded mode. + - Do: move embedded IAM readiness publication, global init-time publication, + and ready-state logging behind startup lifecycle helpers. + - Acceptance: embedded startup still publishes readiness after runtime + service setup, preserves the `runtime readiness` error prefix on failure, + records global init time after successful readiness publication, and logs + the same ready endpoint message after the server handle is built. + - Must preserve: deferred IAM bootstrap readiness behavior, ready-inline + runtime readiness publication, startup failure shutdown signaling, global + init-time publication ordering, and endpoint-address normalization used by + the ready log. + - Verification: focused embedded/lifecycle checks, RustFS lib check, + migration/layer guards, formatting, diff hygiene, Rust risk scan, branch + freshness check, pre-commit quality gate, and three-expert review. + ## Next PRs -1. `pure-move`: continue embedded lifecycle reuse for final server-ready and - lifecycle publication edges. -2. `contract`: continue extension contract coverage for future diagnostics and +1. `contract`: continue extension contract coverage for future diagnostics and profiler handoff surfaces after runtime owners are stable. +2. `pure-move`: continue pruning residual embedded startup-only orchestration + once the lifecycle helpers are merged. ## Pre-Push Review Log | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | R-030 moves embedded runtime service and shutdown cleanup ownership into startup service/shutdown helpers while keeping binary-only runtime services separate. | -| Migration preservation | passed | Embedded non-fatal KMS/audit/notification policy, bucket metadata/IAM ordering, readiness publication, and shutdown cleanup behavior remain unchanged. | -| Testing/verification | passed | Focused embedded/service/shutdown checks, guards, formatting, diff hygiene, Rust risk scan, and full pre-commit passed. | +| Quality/architecture | passed | R-031 keeps embedded server-handle ownership in `embedded.rs` while moving readiness/global-init/ready-log publication into `startup_lifecycle`. | +| Migration preservation | passed | Runtime readiness error wrapping, IAM bootstrap disposition handling, global init-time ordering, and endpoint-address normalization remain unchanged. | +| Testing/verification | passed | Focused embedded/lifecycle checks, guards, formatting, diff hygiene, Rust risk scan, and full pre-commit passed. | ## Verification Notes Passed before push: -- Issue #660 R-030 current slice: - - `cargo test -p rustfs --lib startup_service_components -- --nocapture`: - passed. - - `cargo test -p rustfs --lib startup_services -- --nocapture`: passed; no - matching unit tests currently exist. - - `cargo test -p rustfs --lib startup_shutdown -- --nocapture`: passed. +- Issue #660 R-031 current slice: + - `cargo test -p rustfs --lib startup_lifecycle -- --nocapture`: passed; + no matching unit tests currently exist. - `cargo test -p rustfs --lib embedded -- --nocapture`: passed; no matching unit tests currently exist. - `cargo check -p rustfs --lib`: passed. @@ -2200,8 +2212,8 @@ Passed before push: - `./scripts/check_layer_dependencies.sh`: passed. - `cargo fmt --all --check`: passed. - `git diff --check`: passed. - - Rust risk scan on changed Rust files: passed; only existing doc-example - `Box` / `println!` and existing test-only `panic!`. + - Rust risk scan on changed Rust files: passed; only existing embedded doc + examples use `Box` / `println!`. - `make pre-commit`: passed. - Issue #660 X-012 current slice: diff --git a/docs/architecture/runtime-lifecycle.md b/docs/architecture/runtime-lifecycle.md index 446e5aa66..b41b54f5c 100644 --- a/docs/architecture/runtime-lifecycle.md +++ b/docs/architecture/runtime-lifecycle.md @@ -97,6 +97,13 @@ shutdown cleanup. Embedded-specific behavior still owns warning-only KMS/audit/notification failures, no binary-only background sidecars, no state manager, and the one-shot server handle cleanup used by embedded shutdown. +## Embedded Lifecycle Publication Reuse + +Embedded ready publication should share startup lifecycle helpers for IAM +readiness publication, global init-time publication, and ready-state logging. +Embedded-specific behavior still owns server handle construction, endpoint +address normalization, and process-local shutdown cleanup. + ## AppContext Foundation Early AppContext work should split resolver files and add compatibility tests before diff --git a/rustfs/src/embedded.rs b/rustfs/src/embedded.rs index 1b89e9976..22e6f4335 100644 --- a/rustfs/src/embedded.rs +++ b/rustfs/src/embedded.rs @@ -48,7 +48,7 @@ use crate::config::Config; use crate::server::{ShutdownHandle, start_http_server}; -use crate::startup_iam::publish_ready_for_iam_bootstrap; +use crate::startup_lifecycle::{log_embedded_server_ready, publish_embedded_startup_ready}; use crate::startup_server::init_embedded_startup_listen_context; use crate::startup_services::init_embedded_startup_runtime_services; use crate::startup_shutdown::run_embedded_shutdown_cleanup; @@ -335,15 +335,13 @@ impl RustFSServerBuilder { ServerError::Init(e.to_string()) })?; - publish_ready_for_iam_bootstrap(service_runtime.iam_bootstrap, listen_context.readiness.as_ref(), None) + publish_embedded_startup_ready(service_runtime.iam_bootstrap, listen_context.readiness.as_ref()) .await .map_err(|e| { shutdown_embedded_server(); ServerError::Init(format!("runtime readiness: {e}")) })?; - rustfs_common::set_global_init_time_now().await; - let server = RustFSServer { address: bound_addr, access_key: self.access_key.clone(), @@ -354,15 +352,7 @@ impl RustFSServerBuilder { temp_dir: temp_dir_guard.map(|g| g.keep()), }; - info!( - target: "rustfs::embedded", - component = LOG_COMPONENT_EMBEDDED, - subsystem = LOG_SUBSYSTEM_EMBEDDED, - event = "embedded_server_state", - state = "ready", - "RustFS embedded server ready at http://{}", - server.endpoint_address() - ); + log_embedded_server_ready(server.endpoint_address()); Ok(server) } diff --git a/rustfs/src/startup_lifecycle.rs b/rustfs/src/startup_lifecycle.rs index adf945310..0b9dd6293 100644 --- a/rustfs/src/startup_lifecycle.rs +++ b/rustfs/src/startup_lifecycle.rs @@ -14,21 +14,24 @@ use crate::{ server::{ServiceStateManager, ShutdownHandle, wait_for_shutdown}, - startup_iam::publish_ready_for_iam_bootstrap, + startup_iam::{IamBootstrapDisposition, publish_ready_for_iam_bootstrap}, startup_services::StartupServiceRuntime, startup_shutdown::run_startup_shutdown_sequence, storage_compat::ECStore, }; use rustfs_common::GlobalReadiness; use rustfs_scanner::init_data_scanner; -use std::{io::Result, sync::Arc}; +use std::{io::Result, net::SocketAddr, sync::Arc}; use tokio_util::sync::CancellationToken; use tracing::info; const LOG_COMPONENT_MAIN: &str = "main"; +const LOG_COMPONENT_EMBEDDED: &str = "embedded"; const LOG_SUBSYSTEM_STARTUP: &str = "startup"; +const LOG_SUBSYSTEM_EMBEDDED: &str = "embedded"; const EVENT_SERVER_READY: &str = "server_ready"; const EVENT_SERVER_SHUTDOWN_STATE: &str = "server_shutdown_state"; +const EVENT_EMBEDDED_SERVER_STATE: &str = "embedded_server_state"; pub struct StartupRuntimeLifecycle { pub server_address: String, @@ -98,3 +101,21 @@ pub async fn run_startup_runtime_lifecycle(lifecycle: StartupRuntimeLifecycle) - ); Ok(()) } + +pub async fn publish_embedded_startup_ready(iam_bootstrap: IamBootstrapDisposition, readiness: &GlobalReadiness) -> Result<()> { + publish_ready_for_iam_bootstrap(iam_bootstrap, readiness, None).await?; + rustfs_common::set_global_init_time_now().await; + Ok(()) +} + +pub fn log_embedded_server_ready(endpoint_address: SocketAddr) { + info!( + target: "rustfs::embedded", + component = LOG_COMPONENT_EMBEDDED, + subsystem = LOG_SUBSYSTEM_EMBEDDED, + event = EVENT_EMBEDDED_SERVER_STATE, + state = "ready", + "RustFS embedded server ready at http://{}", + endpoint_address + ); +}