You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Most components are using a "shared state" model (usually Arc<Mutex<T>>) to communicate data. This interface is clunky and may not even be the best approach. Consider modifying these interfaces to improve readability, maintainability. and/or performance.
The main suggestion would be to wrap usage of Arc<Mutex<T>> behind another struct where appropriate. For example, instead of using Arc<Mutex<HashMap<String, DigitalTwinMapEntry>>> in the cartographer and emitter, create a DigitalTwinMap struct which exposes methods such as get(id: String) and set(id: String, value: DigitalTwinMapEntry). The DigitalTwinMap could manage locking the resource as well, meaning that lock statements are not needed by the caller. Callers would likely just need to use Arc<DigitalTwinMap> rather than the more complex type. This wrapper can likely be made generic to avoid code duplication, and the DigitalTwinMap might extend or alias a struct such as SharedMap<TKey, TValue>.
Other things to consider:
Refactor to have reader/writer roles. Most interfaces between components go one way where one component is updating the data and another is reading it. In this case, the "more correct" way to implement this would be with reader or writer access as appropriate.
Refactor to avoid having to copy and maintain separate state where sensible. For example, the emitter copies data from the digital twin map into its own emissions map which has additional metadata. However, each entry in the emitter's map has a corresponding entry in the shared state with the cartographer. If the DigitalTwinMapEntry data type contained fields for this data then the copy would not be necessary, saving both CPU and memory usage. This should be balanced with the impact of truly using shared state like this since the threads accessing the data might be blocked more often, causing delays in updating this shared state.
Refactor to avoid using Arc<Mutex<T>> as the interface between components. Possible options include a channel-based approach or a client-server-style approach. Note that most alternatives (including the possibilities mentioned) would require additional resource consumption, so this should be balanced against the benefits of such an approach.
Acceptance criteria
Components do not use Arc<Mutex<T>> directly to share data (since there are multiple ways to realize this as noted in the description, this is the only acceptance criterion included in this issue)
The text was updated successfully, but these errors were encountered:
Reimplements the cartographer and emitter. Changes include:
- Switch from `Box<dyn Trait>` to generics for pluggable components
- Use a single shared signal store rather than separate shared components between each interface combo
- Move the `DigitalTwinAdapter::find_by_id` call to the cartographer, thereby eliminating the need for digital twin adapters to run a separate thread
- Update the API for providers and the provider proxy to use struct-like enum variants and return `Result` instead of panicking
- Utilize `mockall` for emitter tests instead of the in-memory mock
- Prevent errors on one signal in the cartographer and emitter from taking down the entire app
- Misc minor cleanup
This partially addresses #18, but more work is needed to get provider proxies integrated
Closes#18 by migrating proxies to the signal store model for sharing data.
Also moves some macros related to axum to a shared place since I otherwise needed to copy one of them for the http proxy
Co-authored-by: jorchiu <[email protected]>
Description
Most components are using a "shared state" model (usually
Arc<Mutex<T>>
) to communicate data. This interface is clunky and may not even be the best approach. Consider modifying these interfaces to improve readability, maintainability. and/or performance.The main suggestion would be to wrap usage of
Arc<Mutex<T>>
behind another struct where appropriate. For example, instead of usingArc<Mutex<HashMap<String, DigitalTwinMapEntry>>>
in the cartographer and emitter, create aDigitalTwinMap
struct which exposes methods such asget(id: String)
andset(id: String, value: DigitalTwinMapEntry)
. TheDigitalTwinMap
could manage locking the resource as well, meaning that lock statements are not needed by the caller. Callers would likely just need to useArc<DigitalTwinMap>
rather than the more complex type. This wrapper can likely be made generic to avoid code duplication, and theDigitalTwinMap
might extend or alias a struct such asSharedMap<TKey, TValue>
.Other things to consider:
DigitalTwinMapEntry
data type contained fields for this data then the copy would not be necessary, saving both CPU and memory usage. This should be balanced with the impact of truly using shared state like this since the threads accessing the data might be blocked more often, causing delays in updating this shared state.Arc<Mutex<T>>
as the interface between components. Possible options include a channel-based approach or a client-server-style approach. Note that most alternatives (including the possibilities mentioned) would require additional resource consumption, so this should be balanced against the benefits of such an approach.Acceptance criteria
Arc<Mutex<T>>
directly to share data (since there are multiple ways to realize this as noted in the description, this is the only acceptance criterion included in this issue)The text was updated successfully, but these errors were encountered: