Fast-DDS icon indicating copy to clipboard operation
Fast-DDS copied to clipboard

The Reader's Liveliness state does not change when the connection with the remote Participant is lost

Open i-and opened this issue 1 year ago • 3 comments

Is there an already existing issue for this?

  • [X] I have searched the existing issues

Expected behavior

on_liveliness_changed() should be called when lease_duration expires.

Current behavior

If the communication with the Participant is interrupted, the on_liveliness_changed() is called after 20 seconds instead of the 1.6 seconds specified in the lease_duration parameter

Steps to reproduce

Developed a test based on the HelloWorld example code in accordance with the attached patch. On the Subscriber's side, another Topic Reader is added with the name HelloWorldTopic_2 (created by the argument -a). In addition to the HelloWorldTopic Topic, a Writer can also send the HelloWorldTopic_2 topic (when using the -a argument). To run the test, you need to open three terminals and run the following commands: ./DDSHelloWorldExample subscriber -a ./DDSHelloWorldExample publisher -s 0 -i 2000 ./DDSHelloWorldExample publisher -s 0 -i 2000 -a

After about 10 seconds after launch, press Ctrl-C in the second terminal, which will end the application with one Topic Writer with name HelloWorldTopic. As a result, only one Topic with the name HelloWorldTopic_2 should be received (corresponds to the timestamp 265.837 on the log shown below). After 1.6 seconds after the termination of the first application with the Topic HelloWorldTopic Writer, the on_liveliness_changed() event is expected to occur on the receiving side because the connection with the Participant was lost. But this does not happen at the expected moment in time. The specified event occurs much later - see timestamp 286.365. The difference between the actual and expected moment of occurrence of the event on_liveliness_changed() is 20 seconds, which corresponds to the leaseDuration parameter from DiscoverySettings. Thus, the initiator of the event was the fact that a timeout occurred in PDP, and not in Liveliness subsystem, which is incorrect in this case. At the time of the corresponding timestamp 296.540, the application with the Topic HelloWorldTopic_2 Writer in the third terminal is terminated by pressing Ctrl-C. And in the log we see the correct sequence of events on_liveliness_changed(): a liveliness event occurs at 296.540 with alive_count=0 not_alive_count=1 alive_count_change=-1 not_alive_count_change=1 and then at 314.941 with alive_count=0 not_alive_count=0 alive_count_change=0 not_alive_count_change=-1.

Terminal number 1 (with two Readers as part of one Participant) will take the following form:

Starting 
Subscriber running. Please press enter to stop the Subscriber
252.863 s: Subscriber HelloWorldTopic matched.
253.763 s: on_liveliness_changed() called for Reader HelloWorldTopic alive_count=1 not_alive_count=0 alive_count_change=1 not_alive_count_change=0 last_publication_handle=1.f.f7.f3.2a.12.5d.e1.0.0.0.0.0.0.1.3
254.863 s: HelloWorldTopic receive message: HelloWorld 2 RECEIVED
256.864 s: HelloWorldTopic receive message: HelloWorld 3 RECEIVED
258.865 s: HelloWorldTopic receive message: HelloWorld 4 RECEIVED
259.835 s: Subscriber HelloWorldTopic_2 matched.
260.064 s: on_liveliness_changed() called for Reader HelloWorldTopic_2 alive_count=1 not_alive_count=0 alive_count_change=1 not_alive_count_change=0 last_publication_handle=1.f.f7.f3.33.12.89.8.0.0.0.0.0.0.1.3
260.865 s: HelloWorldTopic receive message: HelloWorld 5 RECEIVED
261.836 s: HelloWorldTopic_2 receive message: HelloWorld 2 RECEIVED
262.866 s: HelloWorldTopic receive message: HelloWorld 6 RECEIVED
263.836 s: HelloWorldTopic_2 receive message: HelloWorld 3 RECEIVED
264.867 s: HelloWorldTopic receive message: HelloWorld 7 RECEIVED
265.837 s: HelloWorldTopic_2 receive message: HelloWorld 4 RECEIVED
267.838 s: HelloWorldTopic_2 receive message: HelloWorld 5 RECEIVED
269.838 s: HelloWorldTopic_2 receive message: HelloWorld 6 RECEIVED
271.839 s: HelloWorldTopic_2 receive message: HelloWorld 7 RECEIVED
273.839 s: HelloWorldTopic_2 receive message: HelloWorld 8 RECEIVED
275.840 s: HelloWorldTopic_2 receive message: HelloWorld 9 RECEIVED
277.841 s: HelloWorldTopic_2 receive message: HelloWorld 10 RECEIVED
279.841 s: HelloWorldTopic_2 receive message: HelloWorld 11 RECEIVED
281.842 s: HelloWorldTopic_2 receive message: HelloWorld 12 RECEIVED
283.843 s: HelloWorldTopic_2 receive message: HelloWorld 13 RECEIVED
285.843 s: HelloWorldTopic_2 receive message: HelloWorld 14 RECEIVED
286.365 s: on_liveliness_changed() called for Reader HelloWorldTopic alive_count=0 not_alive_count=0 alive_count_change=-1 not_alive_count_change=0 last_publication_handle=1.f.f7.f3.2a.12.5d.e1.0.0.0.0.0.0.1.3
286.366 s: Subscriber HelloWorldTopic unmatched.
287.844 s: HelloWorldTopic_2 receive message: HelloWorld 15 RECEIVED
289.845 s: HelloWorldTopic_2 receive message: HelloWorld 16 RECEIVED
291.845 s: HelloWorldTopic_2 receive message: HelloWorld 17 RECEIVED
293.846 s: HelloWorldTopic_2 receive message: HelloWorld 18 RECEIVED
296.540 s: on_liveliness_changed() called for Reader HelloWorldTopic_2 alive_count=0 not_alive_count=1 alive_count_change=-1 not_alive_count_change=1 last_publication_handle=1.f.f7.f3.33.12.89.8.0.0.0.0.0.0.1.3
314.941 s: on_liveliness_changed() called for Reader HelloWorldTopic_2 alive_count=0 not_alive_count=0 alive_count_change=0 not_alive_count_change=-1 last_publication_handle=1.f.f7.f3.33.12.89.8.0.0.0.0.0.0.1.3
314.941 s: Subscriber HelloWorldTopic_2 unmatched.

HelloWorld example code patch:

diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp b/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp
index 86f3e0009..8e3e55cad 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp
@@ -40,7 +40,8 @@ HelloWorldPublisher::HelloWorldPublisher()
 }
 
 bool HelloWorldPublisher::init(
-        bool use_env)
+        bool use_env,
+        bool use_alternative_topic)
 {
     hello_.index(0);
     hello_.message("HelloWorld");
@@ -90,7 +91,7 @@ bool HelloWorldPublisher::init(
     }
 
     topic_ = participant_->create_topic(
-        "HelloWorldTopic",
+        use_alternative_topic? "HelloWorldTopic_2" : "HelloWorldTopic",
         "HelloWorld",
         tqos);
 
@@ -107,6 +108,10 @@ bool HelloWorldPublisher::init(
         publisher_->get_default_datawriter_qos(wqos);
     }
 
+    wqos.liveliness().kind = AUTOMATIC_LIVELINESS_QOS;
+    wqos.liveliness().lease_duration = eprosima::fastrtps::Time_t(1, 000000000);
+    wqos.liveliness().announcement_period = eprosima::fastrtps::Time_t(0, 900000000);
+
     writer_ = publisher_->create_datawriter(
         topic_,
         wqos,
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.h b/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.h
index b764dfc67..b260b962d 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.h
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.h
@@ -36,7 +36,8 @@ public:
 
     //!Initialize
     bool init(
-            bool use_env);
+            bool use_env,
+            bool use_alternative_topic);
 
     //!Publish a sample
     bool publish(
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp b/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp
index 6823a32f4..8b3b5e48b 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp
@@ -32,17 +32,31 @@
 
 using namespace eprosima::fastdds::dds;
 
+std::string get_time()
+{
+    using namespace std::chrono;
+
+    auto t = (duration_cast<duration<double>>(steady_clock::now().time_since_epoch())).count();
+    
+    char buf[256];
+    std::snprintf(buf, sizeof(buf), "%.3f s: ", t);
+    return buf;
+}
+
 HelloWorldSubscriber::HelloWorldSubscriber()
     : participant_(nullptr)
     , subscriber_(nullptr)
     , topic_(nullptr)
+    , topic_2_(nullptr)
     , reader_(nullptr)
+    , reader_2_(nullptr)
     , type_(new HelloWorldPubSubType())
 {
 }
 
 bool HelloWorldSubscriber::init(
-        bool use_env)
+        bool use_env,
+        bool use_additional_reader)
 {
     DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
     pqos.name("Participant_sub");
@@ -106,6 +120,7 @@ bool HelloWorldSubscriber::init(
         subscriber_->get_default_datareader_qos(rqos);
     }
 
+    rqos.liveliness().lease_duration = eprosima::fastrtps::Time_t(1, 600000000);
     reader_ = subscriber_->create_datareader(topic_, rqos, &listener_);
 
     if (reader_ == nullptr)
@@ -113,6 +128,26 @@ bool HelloWorldSubscriber::init(
         return false;
     }
 
+    if (use_additional_reader)
+    {
+        topic_2_ = participant_->create_topic(
+            "HelloWorldTopic_2",
+            "HelloWorld",
+            tqos);
+ 
+        if (topic_2_ == nullptr)
+        {
+            return false;
+        }
+
+        reader_2_ = subscriber_->create_datareader(topic_2_, rqos, &listener_);
+
+        if (reader_2_ == nullptr)
+        {
+            return false;
+        }
+    }
+
     return true;
 }
 
@@ -122,10 +157,18 @@ HelloWorldSubscriber::~HelloWorldSubscriber()
     {
         subscriber_->delete_datareader(reader_);
     }
+    if (reader_2_ != nullptr)
+    {
+        subscriber_->delete_datareader(reader_2_);
+    }
     if (topic_ != nullptr)
     {
         participant_->delete_topic(topic_);
     }
+    if (topic_2_ != nullptr)
+    {
+        participant_->delete_topic(topic_2_);
+    }
     if (subscriber_ != nullptr)
     {
         participant_->delete_subscriber(subscriber_);
@@ -134,18 +177,18 @@ HelloWorldSubscriber::~HelloWorldSubscriber()
 }
 
 void HelloWorldSubscriber::SubListener::on_subscription_matched(
-        DataReader*,
+        DataReader* reader,
         const SubscriptionMatchedStatus& info)
 {
     if (info.current_count_change == 1)
     {
         matched_ = info.total_count;
-        std::cout << "Subscriber matched." << std::endl;
+        std::cout << get_time() << "Subscriber " << reader->get_topicdescription()->get_name() << " matched." << std::endl;
     }
     else if (info.current_count_change == -1)
     {
         matched_ = info.total_count;
-        std::cout << "Subscriber unmatched." << std::endl;
+        std::cout << get_time() << "Subscriber " << reader->get_topicdescription()->get_name() << " unmatched." << std::endl;
     }
     else
     {
@@ -164,11 +207,24 @@ void HelloWorldSubscriber::SubListener::on_data_available(
         {
             samples_++;
             // Print your structure data here.
-            std::cout << "Message " << hello_.message() << " " << hello_.index() << " RECEIVED" << std::endl;
+            std::cout << get_time() << reader->get_topicdescription()->get_name() << " receive message: " << hello_.message() << " " << hello_.index() << " RECEIVED" << std::endl;
         }
     }
 }
 
+void HelloWorldSubscriber::SubListener::on_liveliness_changed(
+        eprosima::fastdds::dds::DataReader* reader,
+        const eprosima::fastdds::dds::LivelinessChangedStatus& status)
+{
+    std::cout << get_time() << "on_liveliness_changed() called" << 
+        " for Reader " << reader->get_topicdescription()->get_name() <<
+        " alive_count=" << status.alive_count <<
+        " not_alive_count=" << status.not_alive_count << 
+        " alive_count_change=" << status.alive_count_change << 
+        " not_alive_count_change=" << status.not_alive_count_change << 
+        " last_publication_handle=" << status.last_publication_handle << "\n";
+}
+
 void HelloWorldSubscriber::run()
 {
     std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.h b/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.h
index ecd897bd5..585f9446f 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.h
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.h
@@ -37,7 +37,8 @@ public:
 
     //!Initialize the subscriber
     bool init(
-            bool use_env);
+            bool use_env,
+            bool use_additional_reader);
 
     //!RUN the subscriber
     void run();
@@ -53,8 +54,10 @@ private:
     eprosima::fastdds::dds::Subscriber* subscriber_;
 
     eprosima::fastdds::dds::Topic* topic_;
+    eprosima::fastdds::dds::Topic* topic_2_;
 
     eprosima::fastdds::dds::DataReader* reader_;
+    eprosima::fastdds::dds::DataReader* reader_2_;
 
     eprosima::fastdds::dds::TypeSupport type_;
 
@@ -79,6 +82,10 @@ private:
                 eprosima::fastdds::dds::DataReader* reader,
                 const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) override;
 
+        void on_liveliness_changed(
+            eprosima::fastdds::dds::DataReader* reader,
+            const eprosima::fastdds::dds::LivelinessChangedStatus& status) override;
+
         HelloWorld hello_;
 
         int matched_;
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp b/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp
index 35870eb67..d0b912b9e 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp
@@ -144,7 +144,8 @@ enum  optionIndex
     HELP,
     SAMPLES,
     INTERVAL,
-    ENVIRONMENT
+    ENVIRONMENT,
+    USE_ADDITIONAL_ENDPOINT
 };
 
 const option::Descriptor usage[] = {
@@ -157,6 +158,7 @@ const option::Descriptor usage[] = {
     { INTERVAL, 0, "i", "interval",          Arg::NumericRange<>,
       "  -i <num>, \t--interval=<num>  \tTime between samples in milliseconds (Default: 100)." },
     { ENVIRONMENT, 0, "e", "env",            Arg::None,       "  -e \t--env   \tLoad QoS from environment." },
+    { USE_ADDITIONAL_ENDPOINT, 0, "a", "add_endpoint", Arg::None, "  -a \t--add_endpoint   \tUse additional Reader or Writer with Topic name HelloWorldTopic_2"},
     { 0, 0, 0, 0, 0, 0 }
 };
 
@@ -188,6 +190,7 @@ int main(
     uint32_t count = 10;
     uint32_t sleep = 100;
     bool use_environment_qos = false;
+    bool use_additional_endpoint = false;
 
     argc -= (argc > 0);
     argv += (argc > 0); // skip program name argv[0] if present
@@ -289,6 +292,12 @@ int main(
         {
             use_environment_qos = true;
         }
+
+        opt = options[USE_ADDITIONAL_ENDPOINT];
+        if (opt)
+        {
+            use_additional_endpoint = true;
+        }
     }
 
     switch (type)
@@ -296,7 +305,7 @@ int main(
         case 1:
         {
             HelloWorldPublisher mypub;
-            if (mypub.init(use_environment_qos))
+            if (mypub.init(use_environment_qos, use_additional_endpoint))
             {
                 mypub.run(count, sleep);
             }
@@ -305,7 +314,7 @@ int main(
         case 2:
         {
             HelloWorldSubscriber mysub;
-            if (mysub.init(use_environment_qos))
+            if (mysub.init(use_environment_qos, use_additional_endpoint))
             {
                 mysub.run();
             }

Fast DDS version/commit

2.13.0

Platform/Architecture

Ubuntu Focal 20.04 amd64

Transport layer

Default configuration, UDPv4 & SHM

Additional context

No response

XML configuration file

No response

Relevant log output

No response

Network traffic capture

No response

i-and avatar Feb 11 '24 20:02 i-and

Hi @i-and Thanks for using Fast DDS and for the report. I could reproduce the behavior and we are currently working on it. Will come back with feedback.

Mario-DL avatar Feb 26 '24 15:02 Mario-DL

Hi @i-and Could you check if the issue is solved with the former PR ?

Mario-DL avatar Mar 05 '24 07:03 Mario-DL

With these changes, the issue has been resolved.

i-and avatar Mar 13 '24 19:03 i-and