-
Notifications
You must be signed in to change notification settings - Fork 502
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
Service RX/TX Request/Response sessions #356
Service RX/TX Request/Response sessions #356
Conversation
…_session #verification
WarningsAsErrors: '*' | ||
HeaderFilterRegex: '.*\.hpp' | ||
AnalyzeTemporaryDtors: false | ||
FormatStyle: file |
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.
Not yet integrated, but just initial version of the config according issue #226
@@ -6,7 +6,7 @@ | |||
|
|||
include(FetchContent) | |||
set(cetl_GIT_REPOSITORY "https://github.com/OpenCyphal/cetl.git") | |||
set(cetl_GIT_TAG "886a0d227a043511eed6b252ea0f788590c50e75") | |||
set(cetl_GIT_TAG "10fbb2b7b89473d68e73db7235848b0692169e5a") |
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.
CETL's main
(with recently merged cetl::unbounded_variant
.
@@ -1071,7 +1071,7 @@ EXCLUDE_PATTERNS = | |||
# wildcard * is used, a substring. Examples: ANamespace, AClass, | |||
# ANamespace::AClass, ANamespace::*Test | |||
|
|||
EXCLUDE_SYMBOLS = | |||
EXCLUDE_SYMBOLS = *::detail::* |
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.
Internal implementation detail won't go to generated docs.
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.
Nice
/// | ||
class SessionDelegate | ||
class IRxSessionDelegate |
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.
Adding I
prefix for anything like an interface (regardless whether it's internal or public stuff) - as it was requested in previous PR.
if (params.subject_id > CANARD_SUBJECT_ID_MAX) | ||
{ | ||
return ArgumentError{}; | ||
} |
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.
Parameters are const (see params_
below), and their subject_id
won't change. So, it makes sense fail early (at make
phase) rather than later during transmissions. The same story for other session factories.
/// Could be either `CanardTransferKindRequest` or `CanardTransferKindResponse`. | ||
/// | ||
template <typename Interface_, typename Params, CanardTransferKind TransferKind> | ||
class SvcRxSession final : public Interface_, private IRxSessionDelegate |
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.
Both service RX sessions (rx request and rx response) are almost the same in terms of structure and functionality. The only slight difference is their interface name, params type and "kind" of canard transfer. So, IMO making template here is fine and justifiable b/c ...:
- it's
detail
-s, not exposed to a user - no code duplication
- both instantiations (see below just after the template) are 100% covered by unit tests (at line, function and branches level). Please see attached (to the PR description) screenshot of coverage stats.
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.
BTW, MessageRxSession
is also very similar, BUT still has its differences (in terms of params validation and anonymous case handling), so it does not fit into such RX template IMO (hence there is minor code duplication - all covered of course by tests).
&subscription_); | ||
(void) result; | ||
CETL_DEBUG_ASSERT(result >= 0, "There is no way currently to get an error here."); | ||
CETL_DEBUG_ASSERT(result > 0, "New subscription supposed to be made."); |
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.
There is no currently path to fail - pre-validation done at factory.
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.
Sorry, why can't this fail?
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.
@thirtytwobits the only possible error condition occurs if we feed invalid arguments, which we pre-validate and know are correct; hence, it can't fail.
{ | ||
::canardRxUnsubscribe(&delegate_.canard_instance(), | ||
TransferKind, | ||
static_cast<CanardPortID>(params_.service_id)); |
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 path fail as well, but if you think its worth to assert I can do it (here and for msg rx session).
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 like the debug asserts as long as we are able to verify them.
/// | ||
/// @see ScatteredBuffer::ScatteredBuffer(AnyStorage&& any_storage) | ||
/// | ||
class IStorage : public cetl::rtti_helper<IStorageTypeIdType> |
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.
Here and there (including in the design doc) we use word "storage" when we talk about Lizard-specific implementation of actual (potentially) scattered storage this "facade" ScatteredBuffer
is using. So, I decided to rename nested Interface
to IMO more meaningful IStorage
.
auto locale = os->imbue(std::locale("en_US")); | ||
*os << std::chrono::duration_cast<std::chrono::microseconds>(duration).count() << "_us"; | ||
auto locale = os->imbue(std::locale("")); | ||
*os << std::chrono::duration_cast<std::chrono::microseconds>(duration).count() << " us"; |
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.
Previous version failed on my "Estonian only" Ubuntu (b/c there is no "en_US" locale there) ;)
BTW, locale stuff here is just to have more human friendly gtest failure output (like 1'000'000 us
vs 1000000 us
without it).
{ | ||
return DestinationNodeCanIdMatcher(node_id); | ||
} | ||
|
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.
All these gmock matchers (and PrintTo
helpers) have no use when all the tests are green (b/c there is no output), but it makes big difference when something goes wrong. Using them (in conjunction with EXPECT_THAT
macro) gives you nice print of what was expected and what actually is. Stay tuned, even more will be added...
@@ -1071,7 +1071,7 @@ EXCLUDE_PATTERNS = | |||
# wildcard * is used, a substring. Examples: ANamespace, AClass, | |||
# ANamespace::AClass, ANamespace::*Test | |||
|
|||
EXCLUDE_SYMBOLS = | |||
EXCLUDE_SYMBOLS = *::detail::* |
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.
Nice
&subscription_); | ||
(void) result; | ||
CETL_DEBUG_ASSERT(result >= 0, "There is no way currently to get an error here."); | ||
CETL_DEBUG_ASSERT(result > 0, "New subscription supposed to be made."); |
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.
Sorry, why can't this fail?
{ | ||
::canardRxUnsubscribe(&delegate_.canard_instance(), | ||
TransferKind, | ||
static_cast<CanardPortID>(params_.service_id)); |
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 like the debug asserts as long as we are able to verify them.
|
||
void run(const TimePoint) final | ||
{ | ||
// Nothing to do here currently. |
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.
/// This value may change arbitrarily at runtime. The transport implementation will query it before every | ||
/// transmission on the port. This value has no effect on the reception pipeline as it can accept arbitrary MTU. | ||
/// | ||
CETL_NODISCARD virtual std::size_t getMtu() const noexcept = 0; |
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.
This is a public API and nothing catastrophic happens if the value isn't used. Please omit CETL_NODISCARD
value
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.
ok, I will do it. But there is separate issue about revising everything in terms of "to discard or not to discard" question.
ContiguousPayload
building moved to transport impl:cetl::unbounded_variant
(instead of formercetl::any
)Also:
*::detail::*
from generated docsCodo coverage: