Skip to content
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

Msg & Svc UDP RX pipelines are implemented. #368

Merged
merged 129 commits into from
Jul 10, 2024
Merged

Msg & Svc UDP RX pipelines are implemented. #368

merged 129 commits into from
Jul 10, 2024

Conversation

serges147
Copy link
Collaborator

@serges147 serges147 commented Jul 5, 2024

Also:

  • "Error" → "Failure" for variant errors.
  • ~100% Coverage:
image

serges147 added 30 commits May 15, 2024 17:33
@serges147 serges147 self-assigned this Jul 5, 2024
@serges147 serges147 marked this pull request as ready for review July 5, 2024 17:30
Copy link
Member

@pavel-kirienko pavel-kirienko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The UDP transport appears to be missing a detailed documentation of the socket construciton policy and the associted error handling approach. It has to be made very explicit that sockets are created ad-hoc.

  • The new error result types look overly convoluted, I recommend keeping the less verbose form -- see my comment in one of the affected places. I understand the desire to have a clearly named pair of types for the success and failure case but it doesn't seem to justify the existence of the extra entities.

include/libcyphal/transport/can/media.hpp Show resolved Hide resolved

private:
// No Sonar `cpp:S5356` b/c we check here low level PMR alignment expectation.
static bool isAligned(cetl::byte* const raw_bytes_ptr, const std::size_t size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why aren't we getting an unused method error here in non-debug builds?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly IDK... what do you propose?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am just surprised that it is accepted. Would it build if you removed the assertion check where this method is referenced?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried - it compiles fine.

@serges147
Copy link
Collaborator Author

The UDP transport appears to be missing a detailed documentation of the socket construciton policy and the associted error handling approach. It has to be made very explicit that sockets are created ad-hoc.

Agree, I will add such documentation.

udpard_node_id_ = node_id;

UdpardUDPIPEndpoint endpoint{};
const std::int8_t result = ::udpardRxRPCDispatcherStart(&rpc_dispatcher_, node_id, &endpoint);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like udpardRxRPCDispatcherStart is going to get called even if the application only cares about broadcast messages. Is there a lot of overhead to udpardRxRPCDispatcherStart? Should we optimize the code to only call this function if the application registers interest in a service?

Copy link
Collaborator Author

@serges147 serges147 Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's called only when node id is set.

From udpard.h header file documentation:

/// The time complexity is constant. This function does not invoke the dynamic memory manager.

I had discussed this with Pavel at initial stage of the PR - we (correct me please @pavel-kirienko if I'm wrong) agreed that calling this is fine even if there will be no later "interest in a service" as you said. Up to 3 TX sockets (per each redundant media) will be made only once for the whole transport instance, and these TX sockets are in use for both messages and services.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, thanks!

include/libcyphal/transport/udp/udp_transport_impl.hpp Outdated Show resolved Hide resolved
include/libcyphal/transport/udp/udp_transport_impl.hpp Outdated Show resolved Hide resolved
include/libcyphal/transport/udp/udp_transport_impl.hpp Outdated Show resolved Hide resolved
include/libcyphal/transport/udp/udp_transport_impl.hpp Outdated Show resolved Hide resolved
Comment on lines +504 to +507
auto media_failure = withMediaRxSocketsFor( //
new_msg_node,
[](const Media&, const IRxSocket&, const UdpardRxSubscription&, const IRxSessionDelegate&)
-> cetl::optional<AnyFailure> { return cetl::nullopt; });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticing that we're using a lot of lambda functions in this code base. Not saying this is necessarily bad, but I think lambdas will be hard to certify at DAL-C and above. Probably fine to leave for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, compilers should be pretty good to optimize them to a simple plain function (or even completely eliminate/inline it). In this case there is no even capturing of anything (see [] empty list), so...
Also, in autosar c++ 14, again afaik, there nothing really against usage of lambda-s in general, yes there are rules, but not really against its usage in general.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I think lambdas will be hard to certify at DAL-C and above

Are they prohibited by high-integrity coding standards?

@@ -717,13 +768,268 @@ class TransportImpl final : private TransportDelegate, public IUdpTransport //
return cetl::nullopt;
}

/// @brief Tries to call an action with a media and its RX socket.
///
/// The RX socket is made on demand if necessary (but `endpoint` parameter should have a value).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we only need to make the RX socket once during initialization? Is this essentially creating a new RX socket every time we call receive?

Copy link
Collaborator Author

@serges147 serges147 Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are made only when there is no one previously created. Such empty condition (namely UniquePtr is equal tonullptr) may happen in two scenarios:

  • the very first call when RX subscription/service is made (see makeMsgRxSession & makeSvcRxSession)
  • on transport run call - when for any reason the first (above) scenario had failed (but the transient error handler said "it's fine, continue!"), user have got a valid RX session, and now this session is part of transport's run life - hence transport tries to "recover" from this empty socket condition by attempting again. Implementation of IMedia may do different strategies in such case.

For example:
a. do nothing, let it be, and very quickly return error again - has relatively small impact
b. really try create a socket again and again on each run cycle until it succeeded eventually.
c. have some kind of "max attempts counter" and do the "b" several times, and then switch to "a"
d. or, make it time based - like occasionally, once in a while, do retry recreate such faulty media socket, but not on every attempt.

Note, that currently we don't have means to "mark" a media as permanently "broken", so yes, at transport level we do retry recreate socket on each run, but once it succeeded we of course stop doing it (b/c we finally got one).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, thank you for the description!

@pavel-kirienko
Copy link
Member

looks good so far


// No Sonar `cpp:S909` b/c it make sense to use `continue` statement here - the corner case of
// "early" (by deadline) transfer drop. Using `if` would make the code less readable and more nested.
continue; // NOSONAR cpp:S909
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, with this helper peekFirstValidUdpardTxItem method there is no need of NOSONAR anymore (for the continue).

@@ -189,7 +189,7 @@ struct PmrRawBytesDeleter final

if ((nullptr != memory_resource_) && (nullptr != raw_bytes_ptr))
{
CETL_DEBUG_ASSERT(isAligned(raw_bytes_ptr, size_bytes_), "Unexpected alignment of the memory buffer.");
// CETL_DEBUG_ASSERT(isAligned(raw_bytes_ptr, size_bytes_), "Unexpected alignment of the memory buffer.");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting usage of isAligned doesn't make it fail on CI... so, it seems that clang-tidy misses it for some reason

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
5.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

@serges147 serges147 merged commit 3a48e90 into main Jul 10, 2024
20 of 21 checks passed
@serges147 serges147 deleted the sshirokov/udp_rx2 branch July 10, 2024 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants