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

Subscription with requested Durability TRANSIENT_LOCAL does not receive events that were published before Subscription created #353

Closed
emersonknapp opened this issue May 17, 2019 · 3 comments · Fixed by #356
Assignees
Labels
bug Something isn't working

Comments

@emersonknapp
Copy link
Contributor

emersonknapp commented May 17, 2019

Bug report

Required Info:

  • Operating System:
    • Ubuntu 18.04
  • Installation type:
    • Source
  • Version or commit hash:
  • DDS implementation:
    • rmw_fastrtps_cpp, rmw_connext_cpp
  • Client library (if applicable):
    • rclpy

Steps to reproduce issue

  • Create a Publisher with depth > 0, durability=RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL
  • The publisher can be either rclpy or rclcpp, it works correctly either way
  • Publish a message
  • Create an rclpy Subscription with the same QoS policy as the Publisher
  • Spin - you should receive the message that was published. An rclcpp Subscription will receive it, an rclpy Subscription will not

rclpy example, Subscription does not receive message

import rclpy
from rclpy.node import Node
from rclpy.qos import QoSDurabilityPolicy
from rclpy.qos import QoSProfile

from std_msgs.msg import String


def main(args=None):
    rclpy.init(args=args)
    topic = 'qos_durability_chatter'

    node = Node('durability_demo')
    qos_profile = QoSProfile(
        depth=1,
        durability=QoSDurabilityPolicy.RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL)
    publisher = node.create_publisher(String, topic, qos_profile)

    message = String()
    message.data = 'PUBLISHER SAYS HI'
    publisher.publish(message)

    subscription = node.create_subscription(  # noqa: F841
        String, topic,
        lambda msg: print('Subscription received: [{}]'.format(msg.data)),
        qos_profile)

    rclpy.spin(node)
    rclpy.shutdown()


if __name__ == '__main__':
    main()

rclcpp same example, Subscription DOES receive message

#include "rclcpp/rclcpp.hpp"

#include "std_msgs/msg/string.hpp"

int main(int argc, char * argv[])
{
  // Force flush of the stdout buffer
  setvbuf(stdout, NULL, _IONBF, BUFSIZ);

  // Configuration and Initialization
  rclcpp::init(argc, argv);
  rclcpp::executors::SingleThreadedExecutor exec;

  std::string topic("qos_durability_chatter");

  auto node = std::make_shared<rclcpp::Node>("durability_demo");

  rclcpp::QoS qos_profile(1);
  qos_profile.transient_local();  // store the message on the publisher indefinitely

  rclcpp::SubscriptionOptions sub_options;
  rclcpp::PublisherOptions pub_options;
  auto publisher = node->create_publisher<std_msgs::msg::String>(topic, qos_profile, pub_options);

  std_msgs::msg::String msg;
  msg.data = "PUBLISHER SAYS HI";
  publisher->publish(msg);

  auto subscription = node->create_subscription<std_msgs::msg::String>(
    topic,
    qos_profile,
    [](const std_msgs::msg::String::SharedPtr msg) -> void
    {
      RCLCPP_INFO(rclcpp::get_logger("DurabilityDemo"),
        "Subscription received: [%s]", msg->data.c_str());
    },
    sub_options
  );
  rclcpp::spin(node);

  // Cleanup
  rclcpp::shutdown();
  return 0;

  return 0;
}

Expected behavior

The Subscriptions from either client library receives the message, even though the Publisher is not actively publishing.

Actual behavior

The rclpy Subscription does not receive the history queue message. The rclcpp Subscription works as expected.

@emersonknapp
Copy link
Contributor Author

I'm beginning to triage this to get a better sense of the root cause. (ping @nuclearsandwich should we add this to https://github.com/orgs/ros2/projects/5 ?)

@emersonknapp
Copy link
Contributor Author

Update: haven't tracked down root cause yet, but updated the issue with much more minimal repro programs.

@emersonknapp
Copy link
Contributor Author

The issue turned out to be straightforward, thankfully!

The default QoS values used in rclpy are not the same as those in rclcpp. rclpy was defaulting reliability=SYSTEM_DEFAULT, whereas rclcpp was using reliability=RELIABLE by default. When I explicitly set the reliability on the Python clients, the examples work as expected. I'll have a fix up for review soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants