Skip to content

phase 20c: EventPublisherHandle trait + drop Arc<EventPublisher> requ…#106

Draft
JustinKovacich wants to merge 1 commit into
feature/phase20b_sd_state_handlefrom
feature/phase20c_event_publisher_handle
Draft

phase 20c: EventPublisherHandle trait + drop Arc<EventPublisher> requ…#106
JustinKovacich wants to merge 1 commit into
feature/phase20b_sd_state_handlefrom
feature/phase20c_event_publisher_handle

Conversation

@JustinKovacich
Copy link
Copy Markdown
Contributor

…irement

Mirrors phase 20b's SdStateHandle work for the second of the two production-path Arc usages flagged by the 20-pre alloc audit (finding E.1). Adds:

  • EventPublisherHandle<R, S, H>: Clone + 'static trait in src/server/event_publisher.rs. Method: fn publisher(&self) -> &EventPublisher<R, S, H>.
  • WrappableEventPublisherHandle<R, S, H>: EventPublisherHandle<...> extension trait with fn wrap(EventPublisher<R, S, H>) -> Self.
  • Arc<EventPublisher<R, S, H>>: EventPublisherHandle + WrappableEventPublisherHandle (alloc-using std-side default; preserves existing behavior).
  • &'static EventPublisher<R, S, H>: EventPublisherHandle (no-alloc bare-metal path; user declares the static, supplies the reference into a future Server::new_with_handles).

Server gains a third type parameter Hep = Arc<EventPublisher<R, S, H>> (default), threaded through the struct decl and all three impl blocks. Field publisher: Arc<EventPublisher<R, S, H>> becomes publisher: Hep. Arc::new(EventPublisher::new(...)) in constructors becomes Hep::wrap(EventPublisher::new(...)). Server::publisher() accessor return type changes from Arc<EventPublisher<R, S, H>> to Hep — non-breaking for std users who pick up the default; bare-metal users get their chosen handle type back.

Existing call sites pick up the Hep default; no churn in tests/, examples/, or any caller. All three Arc impls (SocketHandle, SdStateHandle, EventPublisherHandle) follow the same pattern: Arc<T> for std (alloc), &'static T for bare-metal (no-alloc), Wrappable* extension for the inline- construction path.

Three of four remediation items in the 20-pre alloc audit are now done: the recv buffer (20a), Arc<SdStateManager> (20b), and Arc<EventPublisher> (20c). The last item — combining all three handle types into a single Server::new_with_handles constructor that accepts pre-built handles directly without the wrap step — lands in 20d.

Type-signature width: Server now reads Server<R, S, F, Tm, H = Arc<F::Socket>, Hsd = Arc<SdStateManager>, Hep = Arc<EventPublisher<R, S, H>>>. Three defaults preserve every existing call site. After 20d, a bare-metal caller will spell out all three explicitly via the new constructor, and a std caller will keep accepting all three defaults via Server::new_with_deps.

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)

…irement

Mirrors phase 20b's `SdStateHandle` work for the second of the
two production-path Arc usages flagged by the 20-pre alloc
audit (finding E.1). Adds:

- `EventPublisherHandle<R, S, H>: Clone + 'static` trait in
  `src/server/event_publisher.rs`. Method:
  `fn publisher(&self) -> &EventPublisher<R, S, H>`.
- `WrappableEventPublisherHandle<R, S, H>: EventPublisherHandle<...>`
  extension trait with `fn wrap(EventPublisher<R, S, H>) -> Self`.
- `Arc<EventPublisher<R, S, H>>: EventPublisherHandle + WrappableEventPublisherHandle`
  (alloc-using std-side default; preserves existing behavior).
- `&'static EventPublisher<R, S, H>: EventPublisherHandle`
  (no-alloc bare-metal path; user declares the static, supplies
  the reference into a future `Server::new_with_handles`).

Server gains a third type parameter `Hep = Arc<EventPublisher<R,
S, H>>` (default), threaded through the struct decl and all three
impl blocks. Field `publisher: Arc<EventPublisher<R, S, H>>`
becomes `publisher: Hep`. `Arc::new(EventPublisher::new(...))`
in constructors becomes `Hep::wrap(EventPublisher::new(...))`.
`Server::publisher()` accessor return type changes from
`Arc<EventPublisher<R, S, H>>` to `Hep` — non-breaking for std
users who pick up the default; bare-metal users get their chosen
handle type back.

Existing call sites pick up the `Hep` default; no churn in
`tests/`, `examples/`, or any caller. All three Arc impls
(SocketHandle, SdStateHandle, EventPublisherHandle) follow the
same pattern: `Arc<T>` for std (alloc), `&'static T` for
bare-metal (no-alloc), `Wrappable*` extension for the inline-
construction path.

Three of four remediation items in the 20-pre alloc audit are
now done: the recv buffer (20a), `Arc<SdStateManager>` (20b),
and `Arc<EventPublisher>` (20c). The last item — combining
all three handle types into a single `Server::new_with_handles`
constructor that accepts pre-built handles directly without
the `wrap` step — lands in 20d.

Type-signature width: Server now reads `Server<R, S, F, Tm,
H = Arc<F::Socket>, Hsd = Arc<SdStateManager>, Hep = Arc<EventPublisher<R, S, H>>>`.
Three defaults preserve every existing call site. After 20d, a
bare-metal caller will spell out all three explicitly via the
new constructor, and a std caller will keep accepting all three
defaults via `Server::new_with_deps`.

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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a handle-indirection layer for the server’s EventPublisher, mirroring the existing SocketHandle / SdStateHandle pattern, to reduce hard dependency on Arc<EventPublisher<...>> and support no-alloc sharing strategies (e.g. &'static EventPublisher).

Changes:

  • Added EventPublisherHandle + WrappableEventPublisherHandle traits, with built-in implementations for Arc<EventPublisher<...>> and &'static EventPublisher<...>.
  • Extended Server with a new generic parameter Hep (defaulting to Arc<EventPublisher<...>>) and threaded it through constructors and impl blocks.
  • Updated Server::publisher() to return Hep (the chosen handle type) instead of always returning an Arc<...>.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/server/mod.rs Adds Hep to Server generics, stores the publisher behind Hep, wraps construction via Hep::wrap, and returns Hep from publisher()
src/server/event_publisher.rs Defines EventPublisherHandle / WrappableEventPublisherHandle and provides Arc / &'static implementations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +458 to +460
/// run loop and any external task that wants to publish events
/// (`server.publisher().publish_event(...)`). Two impls ship out
/// of the box, mirroring the pattern established by
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs/examples here assume callers can do server.publisher().publish_event(...), but Server::publisher() now returns the generic Hep handle and EventPublisherHandle does not require Deref<Target = EventPublisher<...>>. That call pattern only works for the built-in Arc<_> / &'static _ handles (via deref), and will not compile for other valid handle types. Consider updating the docs to show the trait-based access pattern (e.g., borrowing via EventPublisherHandle::publisher()), or alternatively add a Deref bound if direct method calls on the handle are intended to be a guaranteed API.

Suggested change
/// run loop and any external task that wants to publish events
/// (`server.publisher().publish_event(...)`). Two impls ship out
/// of the box, mirroring the pattern established by
/// run loop and any external task that wants to publish events.
/// Callers should borrow the underlying publisher via
/// [`EventPublisherHandle::publisher`] before invoking publisher
/// methods (for example,
/// `server.publisher().publisher().publish_event(...)`). Two impls
/// ship out of the box, mirroring the pattern established by

Copilot uses AI. Check for mistakes.
Comment thread src/server/mod.rs
Comment on lines +709 to +713
/// Get a clone of the event-publisher handle for sending events.
///
/// Returns the [`EventPublisherHandle`] type — `Arc<EventPublisher<R,
/// S, H>>` for std users (the default `Hep`),
/// `&'static EventPublisher<R, S, H>` for bare-metal-no-alloc.
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This accessor returns the generic Hep handle, but the surrounding docs imply it can always be used directly for publishing events. Since EventPublisherHandle doesn’t require Deref<Target = EventPublisher<...>>, callers using a custom handle type may need to explicitly borrow the inner publisher via the handle trait method before calling publish_event/etc. Consider adjusting the docs to reflect the guaranteed usage pattern for all Hep implementations (or constrain Hep with Deref if the direct-call ergonomics are intended).

Suggested change
/// Get a clone of the event-publisher handle for sending events.
///
/// Returns the [`EventPublisherHandle`] type — `Arc<EventPublisher<R,
/// S, H>>` for std users (the default `Hep`),
/// `&'static EventPublisher<R, S, H>` for bare-metal-no-alloc.
/// Get a clone of the configured event-publisher handle.
///
/// This returns the generic handle type `Hep` implementing
/// [`EventPublisherHandle`]. For the default handle types this is typically
/// `Arc<EventPublisher<R, S, H>>` on `std` and
/// `&'static EventPublisher<R, S, H>` on bare-metal-no-alloc.
///
/// Callers using a custom `Hep` implementation should use the
/// [`EventPublisherHandle`] trait to borrow/access the underlying
/// [`EventPublisher`] before calling publisher methods such as
/// `publish_event`.

Copilot uses AI. Check for mistakes.
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.

2 participants