-
Notifications
You must be signed in to change notification settings - Fork 44
Open
Labels
Description
RFC: embedded-services v0.2.0 refactor
Iterating on the lessons learned of our current architecture to refine bugs, reduce data races, and alleviate pain points within our current service architecture
Change Log
- 2026-01-27: Initial RFC created
Motivation
The current design of some of the services are tightly coupled, and this makes feature extension and testing expensive and brittle:
- Race conditions + deadlocks: Late‑subscribing patterns, static lists, and mutual service calls can drop messages or deadlock during boot or reset
- Overlapping command paths and implicit API design: Services can have multiple ways of advancing a state machine or enabling a feature, such as message passing via our comms layer IPC. These mechanisms solving the same problem differently, which can lead to duplication of logic and confusion on concretely what is advancing state
- Tight coupling via public statics: Static registries (intrusive lists and channels) block dependency injection, mocking, and unit tests. These should exist at the app level and our services should be generic upon them.
- Type-c/Power policy ID indirection: The type-c service has a concept of “controller/global/local port IDs”, which other subsystems (mainly power policy) must reason about that are not part of their domain
- Hardware variance baked into the subsystem: Supporting multiple PD hardware devices in embedded-services increases crate‑level complexity.
Goals
- Eliminate init race conditions and deadlocks by creating all Channel/Signal receivers before any sender is exposed, and removing late subscriptions.
- Replace static APIs & intrusive lists with explicit handles and trait‑based dependencies for extensibility and unit tests.
- Replace static intrusive lists in the service layer with statics constructed by the app layer and handed into service
init().
- Replace static intrusive lists in the service layer with statics constructed by the app layer and handed into service
- Unify calling paths for controller/port actions; reduce to one coherent API surface.
- Eliminate implicit API design by replacing messaging passing via IPC with direct async calls.
- Maintain feature parity