Consumer: react fast on sync Interest timeout

refs: #5124

Change-Id: Ic28cd6d10e59645c2a209c5efc446ef28b600462
diff --git a/PSync/consumer.cpp b/PSync/consumer.cpp
index f94c6cf..95e3f89 100644
--- a/PSync/consumer.cpp
+++ b/PSync/consumer.cpp
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public License along with
  * PSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #include "PSync/consumer.hpp"
 #include "PSync/detail/state.hpp"
@@ -187,7 +187,7 @@
   using ndn::util::SegmentFetcher;
   SegmentFetcher::Options options;
   options.interestLifetime = m_syncInterestLifetime;
-  options.maxTimeout = m_syncInterestLifetime;;
+  options.maxTimeout = m_syncInterestLifetime;
   options.rttOptions.initialRto = m_syncInterestLifetime;
 
   m_syncFetcher = SegmentFetcher::start(m_face, syncInterest,
@@ -216,9 +216,14 @@
 
   m_syncFetcher->onError.connect([this] (uint32_t errorCode, const std::string& msg) {
     NDN_LOG_TRACE("Cannot fetch sync data, error: " << errorCode << " message: " << msg);
-    ndn::time::milliseconds after(m_rangeUniformRandom(m_rng));
-    NDN_LOG_TRACE("Scheduling after " << after);
-    m_scheduler.schedule(after, [this] { sendSyncInterest(); });
+    if (errorCode == SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
+      sendSyncInterest();
+    }
+    else {
+      ndn::time::milliseconds after(m_rangeUniformRandom(m_rng));
+      NDN_LOG_TRACE("Scheduling sync Interest after: " << after);
+      m_scheduler.schedule(after, [this] { sendSyncInterest(); });
+    }
   });
 }
 
diff --git a/PSync/full-producer.cpp b/PSync/full-producer.cpp
index 3057f1b..430d2ec 100644
--- a/PSync/full-producer.cpp
+++ b/PSync/full-producer.cpp
@@ -119,7 +119,11 @@
 
   m_fetcher->onError.connect([this] (uint32_t errorCode, const std::string& msg) {
     NDN_LOG_ERROR("Cannot fetch sync data, error: " << errorCode << " message: " << msg);
-    if (errorCode == SegmentFetcher::ErrorCode::NACK_ERROR) {
+    // We would like to recover from errors like NoRoute NACK quicker than sync Interest timeout.
+    // We don't react to Interest timeout here as we have scheduled the next sync Interest
+    // to be sent in half the sync Interest lifetime + jitter above. So we would react to
+    // timeout before it happens.
+    if (errorCode != SegmentFetcher::ErrorCode::INTEREST_TIMEOUT) {
       auto after = ndn::time::milliseconds(m_jitter(m_rng));
       NDN_LOG_DEBUG("Schedule sync interest after: " << after);
       m_scheduledSyncInterestId = m_scheduler.schedule(after, [this] { sendSyncInterest(); });
diff --git a/tests/test-consumer.cpp b/tests/test-consumer.cpp
index 4811ebe..269124d 100644
--- a/tests/test-consumer.cpp
+++ b/tests/test-consumer.cpp
@@ -66,14 +66,14 @@
                     ndn::time::milliseconds(4000));
 
   consumer.sendHelloInterest();
-  advanceClocks(ndn::time::milliseconds(4000));
+  advanceClocks(4_s);
   BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
   face.sentInterests.clear();
   consumer.stop();
 
   consumer.m_iblt = ndn::Name("test");
   consumer.sendSyncInterest();
-  advanceClocks(ndn::time::milliseconds(4000));
+  advanceClocks(3999_ms);
   BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
   consumer.stop();
 }
diff --git a/tests/test-partial-sync.cpp b/tests/test-partial-sync.cpp
index 2d5835a..2c648e9 100644
--- a/tests/test-partial-sync.cpp
+++ b/tests/test-partial-sync.cpp
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public License along with
  * PSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #include "PSync/partial-producer.hpp"
 #include "PSync/consumer.hpp"
@@ -181,11 +181,11 @@
   BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
 
   // The sync interest sent after hello will timeout
-  advanceClocks(ndn::time::milliseconds(1000));
+  advanceClocks(ndn::time::milliseconds(999));
   BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
 
   // Next sync interest will bring back the sync data
-  advanceClocks(ndn::time::milliseconds(1500));
+  advanceClocks(ndn::time::milliseconds(1));
   BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
 }
 
@@ -217,7 +217,8 @@
   advanceClocks(ndn::time::milliseconds(10));
   BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 1);
   advanceClocks(ndn::time::milliseconds(10), 100);
-  BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 0);
+  // The next Interest is sent after the first one immediately
+  BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 1);
   advanceClocks(ndn::time::milliseconds(10), 100);
 
   int numSyncInterests = 0;
@@ -226,7 +227,7 @@
       numSyncInterests++;
     }
   }
-  BOOST_CHECK_EQUAL(numSyncInterests, 2);
+  BOOST_CHECK_EQUAL(numSyncInterests, 3);
   BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
 }
 
@@ -411,10 +412,10 @@
     producer->updateSeqNo(longNameToExceedDataSize.toUri() + "-" + to_string(i), 1);
   }
 
-  advanceClocks(ndn::time::milliseconds(1000));
+  advanceClocks(ndn::time::milliseconds(999));
   BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
 
-  advanceClocks(ndn::time::milliseconds(1500));
+  advanceClocks(ndn::time::milliseconds(1));
   BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
 
   // Simulate sending delayed interest for second segment