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

Skip liveliness parts for qos elements with default values #266

Merged
merged 6 commits into from
Aug 28, 2024

Conversation

Yadunund
Copy link
Member

@Yadunund Yadunund commented Aug 22, 2024

This PR is a follow-up to #234.

Instead of convering the qos value to a string and appending to the liveliness token's keyexpression, we only do so when the qos value deviates from the QoS::default_qos(). This reduces the number of bytes we need to pack into the liveliness tokens.

Prior to this PR, the publisher that spins when running ros2 topic pub /chatter std_msgs/msg/String '{data: hello}' --qos-reliability reliable --qos-durability transient_local --qos-depth 42 --qos-history keep_last, the liveliness token would look like

@/liveliness/@ros2_lv/0/169ba0d08c2b76ba4f7e8f99cb450fe/0/4/MP/%/%/_ros2cli_42493/%chatter/std_msgs::msg::dds_::String_/RIHS01_df668c740482bbd48fb39d76a70dfd4bd59db1288021743503259e948f6b1a18/1:1:1,42:9223372036,854775807:9223372036,854775807:1,9223372036,854775807

Now the token looks like

@/liveliness/@ros2_lv/0/5af83680cf352c29b0a98954d16a5470/0/4/MP/%/%/_ros2cli_43208/%chatter/std_msgs::msg::dds_::String_/RIHS01_df668c740482bbd48fb39d76a70dfd4bd59db1288021743503259e948f6b1a18/::,:,:,:,,

The diff better highlights the differences

- @/liveliness/@ros2_lv/0/169ba0d08c2b76ba4f7e8f99cb450fe/0/4/MP/%/%/_ros2cli_42493/%chatter/std_msgs::msg::dds_::String_/RIHS01_df668c740482bbd48fb39d76a70dfd4bd59db1288021743503259e948f6b1a18/1:1:1,42:9223372036,854775807:9223372036,854775807:1,9223372036,854775807
+ @/liveliness/@ros2_lv/0/169ba0d08c2b76ba4f7e8f99cb450fe/0/4/MP/%/%/_ros2cli_42493/%chatter/std_msgs::msg::dds_::String_/RIHS01_df668c740482bbd48fb39d76a70dfd4bd59db1288021743503259e948f6b1a18/::,:,:,:,,

I've tested this PR against the rcl tests and no new errors.

Copy link
Collaborator

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

Overall, this looks great, and is a great improvement. I have one thing I think we should fix inline, but then this should be good to go.

} catch (const std::exception & e) {
RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("Error setting QoS values from strings: %s", e.what());
return std::nullopt;
}

// Helper function to convert string to size_t.
auto str_to_size_t =
[](const std::string & str) -> std::optional<size_t>
[](const std::string & str, const std::size_t default_value) -> std::optional<size_t>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm concerned about the size_t here. In particular, it is not always the case that sizeof(size_t) == sizeof(uint64_t). Yet the deadline, lifespan, and liveliness changes down below assume that it is the case (for the sec and nsec).

What I'm going to suggest instead is that we make this a "real" function, and templatize default_value. Then all of those will get code generated properly.

Something like:

template<typename T>
static std::optional<T> str_to_size_t(const std::string & str, const T default_value)
{
  if (str.empty()) {
    return default_value;
  }
  errno = 0;
  char * endptr;
  size_t num = strtoul(str.c_str(), &endptr, 10);
  if (endptr == str.c_str()) {
    // No values were converted, this is an error
    RMW_SET_ERROR_MSG("no valid numbers available");
    return std::nullopt;
  } else if (*endptr != '\0') {
    // There was junk after the number
    RMW_SET_ERROR_MSG("non-numeric values");
    return std::nullopt;
  } else if (errno != 0) {
    // Some other error occurred, which may include overflow or underflow
    RMW_SET_ERROR_MSG(
      "an undefined error occurred while getting the number, this may be an overflow");
    return std::nullopt;
  }
  return num;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Great suggestion; I've modified accordingly aa5697d

@Yadunund Yadunund force-pushed the yadu/minimal-qos-in-liveliness branch from aa5697d to db537a8 Compare August 26, 2024 02:25
Comment on lines 237 to 238
template<typename T>
std::optional<T> str_to_size_t(const std::string & str, const T default_value)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This whole function doesn't need to live in the header file; we can just keep it as an anonymous namespace function within liveliness_utils.cpp.

}
errno = 0;
char * endptr;
size_t num = strtoul(str.c_str(), &endptr, 10);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thinking about it more today, I realized two problems here:

  1. strtoul is documented as returning an unsigned long, not a size_t. This is an existing bug.
  2. If T ended up being a signed integer, we'd likely do the incorrect thing here. We could fix this either by making the template type only support unsigned (any signed integers would fail to compile), or we could do some other template magic to choose strtoul or strtol as appropriate.

I would say neither of those are blockers, but if you decide not to fix them I'd appreciate a TODO comment explaining what should be improved here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the feedback! I've left 1) as a TODO but addressed 2) with an std::is_signed check. See bd3722f

@ahcorde ahcorde requested a review from clalancette August 27, 2024 07:40
Copy link
Contributor

@ahcorde ahcorde left a comment

Choose a reason for hiding this comment

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

Just a minor nit, otherwise LGTM

rmw_zenoh_cpp/src/detail/liveliness_utils.cpp Show resolved Hide resolved
Signed-off-by: Yadunund <[email protected]>
Copy link
Collaborator

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

Two more nits, then this will be good to go from my perspective.

rmw_zenoh_cpp/src/detail/liveliness_utils.cpp Outdated Show resolved Hide resolved
Comment on lines 26 to 28
#include "logging_macros.hpp"

#include "rmw/error_handling.h"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Both of these can be moved back into liveliness_utils.cpp.

Copy link
Member Author

Choose a reason for hiding this comment

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

oops my bad dd44983

Yadunund and others added 2 commits August 27, 2024 23:42
Signed-off-by: Yadunund <[email protected]>
Copy link
Collaborator

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

This looks great, thanks for iterating.

@Yadunund Yadunund merged commit d2e1225 into rolling Aug 28, 2024
8 checks passed
@Yadunund Yadunund deleted the yadu/minimal-qos-in-liveliness branch August 28, 2024 01:52
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