Queued messages do not get sent when shutting down a publisher
I noticed that when calling
publisher.shutdown(), the messages that are queued for publishing simply get destroyed with the publisher. I could not find any documentation that specified this behavior.
It seems unintuitive to me, especially if I compare to other systems. For example, when I write an e-mail, click send, and close the mail application, it will not just delete the e-mail if it is not yet sent.
I know that when ROS started, it was designed to send streams of data where the loss of a few messages was not important, but this is not always the case. In the applications developed in my project for example, every message is important, and many of them are sent only once. I would therefore need a way to shut down a publisher without losing any messages.
Here's an example that shows the problem:
#include <ros/ros.h> #include <std_msgs/String.h> int main(int argc, char** argv) { ros::init(argc, argv, "MyPublisher"); ros::NodeHandle nh("~"); ros::Rate oneSecond(1); int num = 1; while(ros::ok()) { ros::Publisher pub = nh.advertise<std_msgs::String > ("/MyTopic", 10); // Waits for the subscribers to connect oneSecond.sleep(); std_msgs::String msg; std::stringstream ss; ss << "Hello World! " << num++; msg.data = ss.str(); pub.publish(msg); pub.shutdown(); // Moving this line above the shutdown solves the problem oneSecond.sleep(); } return 0; }
In that example, the subscribers never get any message, because the publisher gets shut down before its messages get sent. Swapping
shutdown() and
sleep() solves the problem.
I am wondering how to solve this properly. Waiting a second before every
shutdown() in my application is not nice, and is problematic when it is in the GUI thread (the whole GUI would freeze). Also, I am not guaranteed that one second is enough.
You are correct. Messages do get lost. Most nodes that care about it do something similar to your sleep before shutdown. It would be nice to have a cleaner solution.