server: SdStateHandle trait + drop Arc<SdStateManager> requirement#105
server: SdStateHandle trait + drop Arc<SdStateManager> requirement#105JustinKovacich wants to merge 1 commit into
Conversation
Adds `SdStateHandle` + `WrappableSdStateHandle` traits in `src/server/sd_state.rs` and threads them through `Server` as a new `Hsd` type parameter (default `Arc<SdStateManager>`). Mirrors the pattern established by 19f's `SocketHandle` / `WrappableSocketHandle`. Same shape, same Send/Sync defaults (neither bound at trait level — caller adds at use sites). Two impls ship: - `Arc<SdStateManager>: SdStateHandle + WrappableSdStateHandle` (the existing default; preserves std-side behavior). - `&'static SdStateManager: SdStateHandle` (no-alloc; user declares `static SD_STATE: SdStateManager = SdStateManager::new();` and supplies `&SD_STATE` via a future `Server::new_with_handles` constructor). `SdStateManager` itself becomes `pub` and `SdStateManager::new()` becomes `pub const fn` so the static-storage pattern compiles. The internal methods (`next_session_id_with_reboot_flag`, `reboot_flag`, `send_offer_service`) stay `pub(super)` — consumers shouldn't call them directly; they go through Server. Server's existing `new_with_deps` / `new_passive_with_deps` constructors require `Hsd: WrappableSdStateHandle` because they build the manager internally via `SdStateManager::new()` then `Hsd::wrap(...)`. The future `Server::new_with_handles` will take `Hsd: SdStateHandle` directly (no `wrap` step), enabling the no-alloc path with `&'static SdStateManager`. `announcement_loop`'s method-level `where` clause picks up the new `Hsd: Send + Sync` bound, mirroring the existing `H: Send + Sync` and `F: Send + Sync` bounds. The `_local` variant has no such requirement and works for any `Hsd: SdStateHandle`. Type-signature width: Server now reads `Server<R, S, F, Tm, H = Arc<F::Socket>, Hsd = Arc<SdStateManager>>`. Both defaults preserve every existing call site — `Server<R, S, F, Tm>` and `Server<R, S, F, Tm, Arc<SomeSocket>>` both still resolve correctly. No churn in `tests/` or `examples/`. Clears 20-pre alloc audit's category-E.2 finding. Combined with the 4f9d36e recv-buffer split, two of the four "no-alloc Server" remediation items are done. What this leaves: - E.1: `Arc<EventPublisher<R, S, H>>` field on Server. Same shape via an `EventPublisherHandle` trait — next branch. - D: `Server::new_with_handles` constructor that takes pre-built `H` + `Hsd` (and the future `Hep` for E.1) directly, skipping the `wrap` step. Lands after E.1 so the constructor's parameter list is final. Gates green: - cargo fmt --check - cargo clippy --tests (2 pre-existing warnings, unrelated) - cargo build --workspace --all-targets - cargo build --no-default-features --features client,server,bare_metal - cargo build -p simple-someip-embassy-net --target thumbv7em-none-eabihf - cargo test --features client-tokio,server-tokio --test client_server -- --test-threads=1 (11/11) - cargo test --features client,server,bare_metal --test bare_metal_e2e (2/2) - cargo test -p simple-someip-embassy-net --test loopback (3/3) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a handle abstraction for server-side SD session state (SdStateHandle / WrappableSdStateHandle) and threads it through Server as a new type parameter (Hsd, defaulting to Arc<SdStateManager>), enabling future no-alloc usage patterns without requiring Arc<SdStateManager>.
Changes:
- Add
SdStateHandleandWrappableSdStateHandletraits plus implementations forArc<SdStateManager>and&'static SdStateManager. - Make
SdStateManagerpublic andSdStateManager::new()apub const fnto support static-storage construction. - Update
Serverto store SD state behindHsdand useSdStateHandle::sd_state()at call sites; add method-levelSend + Syncbounds forannouncement_loop.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/server/sd_state.rs | Makes SdStateManager public/const-constructible and adds SD-state handle traits + impls. |
| src/server/mod.rs | Adds Hsd type parameter to Server and migrates SD-state usage to the new handle abstraction. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// once, then [`RebootFlag::Continuous`] permanently — `SdStateManager` | ||
| /// tracks that transition and exposes it via [`Self::reboot_flag`] so every | ||
| /// server-side SD emission path reads from a single source of truth. | ||
| #[derive(Debug)] | ||
| pub(super) struct SdStateManager { | ||
| pub struct SdStateManager { |
There was a problem hiding this comment.
SdStateManager is now public, but its rustdoc still claims it "exposes" the reboot state via Self::reboot_flag (and links to it). reboot_flag is #[cfg(test)] pub(super), so it won’t exist in normal builds and the public docs are now inaccurate / can produce a broken intra-doc link. Suggest updating this doc to describe the public surface (e.g., refer to next_session_id_with_reboot_flag semantics or state that reboot-flag tracking is internal to Server) and remove the Self::reboot_flag link rather than making that method public.
Adds
SdStateHandle+WrappableSdStateHandletraits insrc/server/sd_state.rsand threads them throughServeras a newHsdtype parameter (defaultArc<SdStateManager>). Mirrors the pattern established by 19f'sSocketHandle/WrappableSocketHandle. Same shape, same Send/Sync defaults (neither bound at trait level — caller adds at use sites).Two impls ship:
Arc<SdStateManager>: SdStateHandle + WrappableSdStateHandle(the existing default; preserves std-side behavior).&'static SdStateManager: SdStateHandle(no-alloc; user declaresstatic SD_STATE: SdStateManager = SdStateManager::new();and supplies&SD_STATEvia a futureServer::new_with_handlesconstructor).SdStateManageritself becomespubandSdStateManager::new()becomespub const fnso the static-storage pattern compiles. The internal methods (next_session_id_with_reboot_flag,reboot_flag,send_offer_service) staypub(super)— consumers shouldn't call them directly; they go through Server.Server's existing
new_with_deps/new_passive_with_depsconstructors requireHsd: WrappableSdStateHandlebecause they build the manager internally viaSdStateManager::new()thenHsd::wrap(...). The futureServer::new_with_handleswill takeHsd: SdStateHandledirectly (nowrapstep), enabling the no-alloc path with&'static SdStateManager.announcement_loop's method-levelwhereclause picks up the newHsd: Send + Syncbound, mirroring the existingH: Send + SyncandF: Send + Syncbounds. The_localvariant has no such requirement and works for anyHsd: SdStateHandle.Type-signature width: Server now reads
Server<R, S, F, Tm, H = Arc<F::Socket>, Hsd = Arc<SdStateManager>>. Both defaults preserve every existing call site —Server<R, S, F, Tm>andServer<R, S, F, Tm, Arc<SomeSocket>>both still resolve correctly. No churn intests/orexamples/.Clears 20-pre alloc audit's category-E.2 finding. Combined with the 4f9d36e recv-buffer split, two of the four "no-alloc Server" remediation items are done.
What this leaves:
Arc<EventPublisher<R, S, H>>field on Server. Same shape via anEventPublisherHandletrait — next branch.Server::new_with_handlesconstructor that takes pre-builtH+Hsd(and the futureHepfor E.1) directly, skipping thewrapstep. Lands after E.1 so the constructor's parameter list is final.Gates green: