Start initialization phase on application nack
PartialProducer: append sequence number in hello data
refs: #4693
Change-Id: I56ac3e331a92b9a79d3bf360571df2914a5374aa
diff --git a/src/consumer.cpp b/src/consumer.cpp
index 545acea..301828b 100644
--- a/src/consumer.cpp
+++ b/src/consumer.cpp
@@ -92,10 +92,34 @@
NDN_LOG_TRACE("m_iblt: " << std::hash<std::string>{}(m_iblt.toUri()));
State state(data.getContent());
+ std::vector<MissingDataInfo> updates;
+ std::vector<ndn::Name> availableSubscriptions;
- NDN_LOG_DEBUG("Content: " << state);
+ for (const auto& content : state.getContent()) {
+ ndn::Name prefix = content.getPrefix(-1);
+ uint64_t seq = content.get(content.size()-1).toNumber();
+ if (m_prefixes.find(prefix) == m_prefixes.end()) {
+ // In case this the first prefix ever received via hello data,
+ // add it to the available subscriptions
+ availableSubscriptions.push_back(prefix);
+ }
+ else if (seq > m_prefixes[prefix]) {
+ // Else this is not the first time we have seen this prefix,
+ // we must let application know that there is missing data
+ // (scenario: application nack triggers another hello interest)
+ updates.push_back(MissingDataInfo{prefix, m_prefixes[prefix] + 1, seq});
+ m_prefixes[prefix] = seq;
+ }
+ }
- m_onReceiveHelloData(state.getContent());
+ NDN_LOG_DEBUG("Hello Data: " << state);
+
+ m_onReceiveHelloData(availableSubscriptions);
+
+ if (!updates.empty()) {
+ NDN_LOG_DEBUG("Updating application with missed updates");
+ m_onUpdate(updates);
+ }
}
void
@@ -140,8 +164,8 @@
m_iblt = syncDataName.getSubName(syncDataName.size()-1, 1);
if (data.getContentType() == ndn::tlv::ContentType_Nack) {
- NDN_LOG_DEBUG("Received application Nack from producer, renew sync interest");
- sendSyncInterest();
+ NDN_LOG_DEBUG("Received application Nack from producer, send hello again");
+ sendHelloInterest();
return;
}
diff --git a/src/consumer.hpp b/src/consumer.hpp
index 47825a9..9b30d8d 100644
--- a/src/consumer.hpp
+++ b/src/consumer.hpp
@@ -46,11 +46,17 @@
* @brief Consumer logic to subscribe to producer's data
*
* Application needs to call sendHelloInterest to get the subscription list
- * in ReceiveHelloCallback. It can then add the desired names using addSubscription.
+ * in psync::ReceiveHelloCallback. It can then add the desired names using addSubscription.
* Finally application will call sendSyncInterest. If the application adds something
* later to the subscription list then it may call sendSyncInterest again for
* sending the next sync interest with updated IBF immediately to reduce any delay in sync data.
* Whenever there is new data UpdateCallback will be called to notify the application.
+ *
+ * If consumer wakes up after a long time to sync, producer may not decode the differences
+ * with its old IBF successfully and send an application nack. Upon receiving the nack,
+ * consumer will send a hello again and inform the application via psync::ReceiveHelloCallback
+ * and psync::UpdateCallback.
+ *
* Currently, fetching of the data needs to be handled by the application.
*/
class Consumer
@@ -97,6 +103,7 @@
* @brief Add prefix to subscription list
*
* @param prefix prefix to be added to the list
+ * @return true if prefix is added, false if it is already present
*/
bool
addSubscription(const ndn::Name& prefix);
diff --git a/src/partial-producer.cpp b/src/partial-producer.cpp
index 73fb677..d8d98a5 100644
--- a/src/partial-producer.cpp
+++ b/src/partial-producer.cpp
@@ -79,8 +79,8 @@
State state;
- for (const auto& p : m_prefixes) {
- state.addContent(p.first);
+ for (const auto& prefix : m_prefixes) {
+ state.addContent(ndn::Name(prefix.first).appendNumber(prefix.second));
}
NDN_LOG_DEBUG("sending content p: " << state);