-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a ClientTrait for RustSDK #142
base: main
Are you sure you want to change the base?
Create a ClientTrait for RustSDK #142
Conversation
46bd034
to
ddbc538
Compare
ddbc538
to
bae6f53
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #142 +/- ##
==========================================
+ Coverage 59.38% 59.47% +0.09%
==========================================
Files 34 34
Lines 15137 15085 -52
==========================================
- Hits 8989 8972 -17
+ Misses 6148 6113 -35 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no functional test has been done yet.
lib/kuksa/src/lib.rs
Outdated
type DatapointType = HashMap<String, proto::v1::Datapoint>; | ||
type PathType = Vec<String>; | ||
type SubscribeType = Self::PathType; | ||
type PublishResponseType = (); | ||
type GetResponseType = Vec<DataEntry>; | ||
type SubscribeResponseType = tonic::Streaming<proto::v1::SubscribeResponse>; | ||
type ProvideResponseType = tonic::Streaming<proto::v1::SubscribeResponse>; | ||
type ActuateResponseType = (); | ||
type MetadataResponseType = Vec<DataEntry>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that the types are closely coupled to the parameters / return values of the corresponding grpc interface methods but right now the types selected here feel arbritrarily chosen and not really fitting to their "type alias".
Maybe this is just a naming thingy and clarity can be increased by making clear what kind of type they are, like ParameterType, ReturnType,...
Like, why is a DatapointType
a HashMap<String, Datapoint>
? I would more expect like DatapointType
to be proto::v1::Datapoint
and then somewhere it uses HashMap<String, DatapointType>
or similar.
A PathType
could be a String
, and sometimes (e.g. get) it's simply used as PathType
and sometimes (e.g. subscribe) it's used as Vec<PathType>
. However I did not play this through if this model would hold for all the implementors (sdv, val.v1, val.v2).
Please think a bit more about how to increase clarity e.g. by renaming the ...Type
or by aligning the implementations.
lib/common/src/lib.rs
Outdated
type MetadataResponseType; | ||
|
||
// from deeply embedded layer providing sensor values (to keep backwards compatibility the naming is different for the corresponding interfaces) | ||
// if we do not want to put in the effort just give an unimplented error for the function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// if we do not want to put in the effort just give an unimplented error for the function | |
// if we do not want to put in the effort just give an unimplemented error for the function |
It's a weird suggestion to make :D do we expect anywhere that this would apply, e.g. in sdv? shouldn't we at least make sure for val.v1 and val.v2 that the function set should be similar and implemented (exceptions of course do apply e.g. for the target_value thingies which no longer exist in v2, but maybe this means we shouldn't expose it in ClientTrait anymore?)
If I understood correctly the ClientTrait methods will just call the existing methods, like ClientTrait#publish would call val.v1 set with Field.VALUE while ClientTrait#actuate would call set with Field.TARGET_VALUE
lib/common/src/lib.rs
Outdated
) -> Result<Self::PublishResponseType, ClientError>; | ||
|
||
// from application getting sensor values (to keep backwards compatibility the naming is different for the corresponding interfaces) | ||
// if we do not want to put in the effort just give an unimplented error for the function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// if we do not want to put in the effort just give an unimplented error for the function | |
// if we do not want to put in the effort just give an unimplemented error for the function |
lib/common/src/lib.rs
Outdated
// from povider side pick up actuation requests (to keep backwards compatibility the naming is different for the corresponding interfaces) | ||
// if we do not want to put in the effort just give an unimplented error for the function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// from povider side pick up actuation requests (to keep backwards compatibility the naming is different for the corresponding interfaces) | |
// if we do not want to put in the effort just give an unimplented error for the function | |
// from provider side: pick up actuation requests (to keep backwards compatibility the naming is different for the corresponding interfaces) | |
// if we do not want to put in the effort just give an unimplemented error for the function |
lib/common/src/lib.rs
Outdated
// from povider side pick up actuation requests (to keep backwards compatibility the naming is different for the corresponding interfaces) | ||
// if we do not want to put in the effort just give an unimplented error for the function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// from povider side pick up actuation requests (to keep backwards compatibility the naming is different for the corresponding interfaces) | |
// if we do not want to put in the effort just give an unimplented error for the function | |
// from provider side: pick up actuation requests (to keep backwards compatibility the naming is different for the corresponding interfaces) | |
// if we do not want to put in the effort just give an unimplemented error for the function |
None | ||
} | ||
}; | ||
let datapoint_entries = handle_get_metadata(vec![path], client).await.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't simply unwrapping the result here crash the application in case of an err? might be a rare case though as this only happens when cli::print_error(...) or prin_resp_err_fm fails - might be neglectable.
@@ -329,20 +331,9 @@ pub async fn kuksa_main(_cli: Cli) -> Result<(), Box<dyn std::error::Error>> { | |||
|
|||
let pattern = vec!["**"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional: could be inlined
); | ||
} else { | ||
let name = entry.path.clone(); | ||
println!("No entry metadata for {name}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
println!("No entry metadata for {name}"); | |
println!("No metadata entry for {name}"); |
&mut self, | ||
paths: Self::PathType, | ||
) -> Result<Self::ProvideResponseType, ClientError> { | ||
println!("Actuation concept has changed with kuksa.val.v2 only supported by it! Defaulting to subscribing to target values."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the sdk use println! or better one of the log macros, like warn!? mutiple occurrences
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm warn would be more suitable yes.
type MetadataResponseType; | ||
|
||
// from deeply embedded layer providing sensor values (to keep backwards compatibility the naming is different for the corresponding interfaces) | ||
// if we do not want to put in the effort just give an unimplemented error for the function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really like the idea of having traits here, just one thing:
what about splitting interfaces? like creating a generic interface which cover common cases from all the APIs like subscribe, publish, etc and an specific traits which covers the target_values use cases, etc?
Something like:
trait GenericSDK { fn subscribe(&self); }
trait TargetValueSDK: GenericSDK { fn set_target_values(&self); }
If I am a sdk user for kuksa_val_v2, it would be confuse to see set_target_values, etc methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm yes but I thought a little bit about managing backwards compatibility. For the sdk agree that it looks strange for people. And for now we might not need backwards compatibility. However I will think about generic sdk and additions.
For handling the Rust SDK and preparing to make it an own crate this introduces a
ClientTrait
. With this the maintenance of the soon-to-be Rust SDK will be easy and manageable.