docs: add design for abstraction layer API to be used by user code#46
Conversation
|
|
||
| package "Design Goals" as DesignGoals {} | ||
|
|
||
| package "API Layer between user code and concrete SOVD client implementation" as DesignGoals.Goal01 {} |
There was a problem hiding this comment.
should it be "and concrete SOVD server implementation"?
There was a problem hiding this comment.
No, since this API layer is intended to be located on top of a specific client implementation (binding) which performs the actual communication with the SOVD server.
There was a problem hiding this comment.
@stmuench so this is not the API layer between SOVD server and Service APP (-> high level architecture)? But this API layer is on Client side?
I´m a bit confused, because this PR was introduced as "This is a proposal on the API between Applications and SOVD Server". Or maybe with "Applications" it was meant applications on SOVD client side...
Please create a reference from this design to the "OpenSOVD High Level Architecture"
| package "hence, user code must provide certain pieces of information as depicted by this design upon registration of SOVD Operations and/or Data Resources" as DesignGoals.Goal02.Note01 {} | ||
|
|
||
| package "user code shall have minimal hassle w.r.t. to creating as well as having to populate native SOVD reply payloads" as DesignGoals.Goal03 {} | ||
| package "ideally, the API layer shall create native SOVD data structures and populate these from the user code's data structures, e.g. to JSON" as DesignGoals.Goal03.Note01 {} |
There was a problem hiding this comment.
do we expect, that data conversion also to be considered in the API layer?
There was a problem hiding this comment.
Ideally, yes. Feasibility is nonetheless subject to be demonstrated.
| +With<UDSServiceType>(Identifier, Args&&...) : DiagnosticServicesCollectionBuilder& | ||
|
|
||
| .. native SOVD APIs .. | ||
| +With<ReadOnlyDataResourceType>(Identifier, JsonSchemaView, DataCategoryIdentifier, optional<DataGroupIdentifier>, Args&&...) : DiagnosticServicesCollectionBuilder& |
There was a problem hiding this comment.
Is the DataCategoryIdentifier an output from the user in this design?
I guess it should be more a configuration item, as the DataCategory is a mandatory attribute in the SOVD response and will be not provided by the legacy UDS API
There was a problem hiding this comment.
I guess for legacy functionality, we would simply provide some predefined category identifier implicitly
There was a problem hiding this comment.
When querying data items from an SOVD Server, users should also see the UDS ones and not only native SOVD-exposed ones. Hence, we need to find a way to merged them, if we want that.
On the other hand, exposing legacy UDS functionality under a custom predefined category would have significantly less implementation efforts and is anyways only expected for a rather short transition period. Ultimately, all apps are subject to get migrated the native SOVD APIs.
| } | ||
|
|
||
| interface Operation { | ||
| API definition for SOVD operations |
There was a problem hiding this comment.
Is this user interface for user code on HPC? On an HPC we have typically no I/O Control
There was a problem hiding this comment.
I/O Control seems to be only relevant for ECUs which have dedicated I/O ports. And HPCs typically do not have such.
71b5bd7 to
2c9baca
Compare
2c9baca to
15e2633
Compare
15e2633 to
e34629d
Compare
| std::pmr::memory_resource& memory_resource_; | ||
| }; | ||
|
|
||
| mw::diag::Result<std::unique_ptr<mw::diag::DiagnosticServicesCollection>> |
There was a problem hiding this comment.
All the unique_ptr instances should carry an allocator with them that makes them pmr aware.
There was a problem hiding this comment.
replaced unique_ptrs by shared_ptrs to be able to use std::allocate_shared for allocator-aware smartptr creation
There was a problem hiding this comment.
But that changes ownership semantics, and I have the feeling that this is an undesired side effect. Wouldn't it be better to add a stateful deleter that carries the memory resource the unique_pointer shall use to deallocate the managed pointer?
There was a problem hiding this comment.
S-CORE's score::cpp::pmr::unique_ptr does not support std::pmr::memory_resource yet (see here and here). Hence, I would have to implement that first (if possible at all). That's why I thought that sticking to utilities from the C++ standard might be the better choice. Ownership itself does not change here since the returned shared_ptr will not be kept by the builder and hence a ref_count of 1 upon return. Then, it's up to the user to decide how to proceed with it.
lh-sag
left a comment
There was a problem hiding this comment.
Maybe this API should move to SCORE instead of opensovd.
e34629d to
ce5e869
Compare
ce5e869 to
93a905d
Compare
93a905d to
63dee81
Compare
| } | ||
|
|
||
| class "DiagnosticServicesCollection" as SOVDDiagnosticServicesCollection { | ||
| +explicit DiagnosticServicesCollection(DiagnosticEntity&, std::pmr::memory_resource&) |
There was a problem hiding this comment.
Taking DiagnosticEntity& will creates dangling reference risk, if entity destroyed, Shared ownership can be the option here.
There was a problem hiding this comment.
True. But this is basically C++ idiomatic. But let me add a comment here which states that the entity is simply required to outlive the collection
| +With<OperationType>(Identifier, OperationInvocationPolicy, std::optional<TranslationIdentifier>, Args&&...) : DiagnosticServicesCollectionBuilder& | ||
|
|
||
| .. final step .. | ||
| +Build() : mw::diag::Result<std::shared_ptr<DiagnosticServicesCollection>> |
There was a problem hiding this comment.
Returning shared_ptr but consuming non-owning builder is inconsistent. Build() should consume the builder.
There was a problem hiding this comment.
What do you mean by consuming here for C++?
There was a problem hiding this comment.
The builder pattern is often single use and it should show clear ownership transfer. It should return unique_ptr.
Build() && : Result<unique_ptr>
|
|
||
| entity ByteSequence { | ||
| <<alias>> | ||
| ByteSequence = std::span<const ByteType> |
There was a problem hiding this comment.
What is ByteType? Is it uint8_t, std::byte or char?
| } | ||
|
|
||
| class DiagnosticEntity { | ||
| using Identifier = std::pmr::string |
There was a problem hiding this comment.
String based identifiers can be error prone, strong typing will prevent accidental mixing.
using Identifier = std::string_view, also does not create a distinct type, code can accidentally pass wrong identifiers.
|
|
||
| class TranslationIdentifier {} | ||
| class DataCategoryIdentifier {} | ||
| class DataGroupIdentifier {} |
There was a problem hiding this comment.
Unclear how to construct or use these(Wrapper types or alias or just tag). Strong typing will prevents accidental misuse (e.g. passing a DataGroupIdentifier where TranslationIdentifier is expected). Compile-time type safety >> runtime checks.
@lh-sag but then we would not have any API layer in opensovd. We thought that S-CORE should simply consume this one as-is and we maintain the API's stability here in opensovd. Or would you have a different opinion here? |
Summary
Checklist
Related
Notes for Reviewers