Adding possibility to set lifetime when publishing content using the http helper. 42/7842/1
authorMauro Sardara <[email protected]>
Fri, 28 Jul 2017 17:37:14 +0000 (19:37 +0200)
committerMauro Sardara <[email protected]>
Fri, 28 Jul 2017 17:37:14 +0000 (19:37 +0200)
Change-Id: I0107bb216e961c189a62f5c6bb3b22fc563919a7
Signed-off-by: Mauro Sardara <[email protected]>
apps/http/icnet_http_echo_server.cc
icnet/http/icnet_http_server_publisher.cc
icnet/http/icnet_http_server_publisher.h
icnet/transport/icnet_transport_content_store.cc
icnet/transport/icnet_transport_content_store.h
icnet/transport/icnet_transport_socket_producer.cc

index 17bdb69..223646a 100644 (file)
@@ -26,11 +26,17 @@ void onPayload(std::shared_ptr<HTTPServerPublisher> &publisher, const uint8_t *b
   std::cout << string << std::endl;
 
   std::stringstream response;
-  response << "HTTP/1.0 200 OK\r\n" << "Content-Length: " << size << "\r\n\r\n" << string;
+  response << "HTTP/1.1 200 OK\r\n" << "Content-Length: " << size << "\r\n\r\n" << string;
   std::string response_string = response.str();
+  std::chrono::milliseconds expiry_time(std::chrono::milliseconds(4000 * 1000));
+
 
   std::thread t([publisher, response_string]() {
-    publisher->publishContent((uint8_t *) response_string.data(), response_string.size(), 0, true);
+    publisher->publishContent((uint8_t *) response_string.data(),
+                              response_string.size(),
+                              std::chrono::milliseconds(transport::default_values::content_object_expiry_time),
+                              0,
+                              true);
     publisher->serveClients();
   });
 
index 92b41e6..e42154b 100644 (file)
@@ -63,13 +63,15 @@ HTTPServerPublisher &HTTPServerPublisher::setTimeout(uint32_t timeout) {
   return *this;
 }
 
-void HTTPServerPublisher::publishContent(const uint8_t *buf, size_t buffer_size, const int response_id, bool is_last) {
+void HTTPServerPublisher::publishContent(const uint8_t *buf, size_t buffer_size, std::chrono::milliseconds content_lifetime, const int response_id, bool is_last) {
   if (producer_) {
 #ifdef __ANDROID__
     __android_log_print(ANDROID_LOG_DEBUG, "HTTP_SERVER_PUBLISHER", "Replying to %s", const_cast<transport::Name &>(content_name_).toString().c_str());
 #else
     std::cout << "Replying to " << content_name_ << std::endl;
 #endif
+    producer_->setSocketOption(transport::GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME, static_cast<int>(content_lifetime.count()));
+
     producer_->produce(content_name_, buf, buffer_size, response_id, is_last);
   }
 }
index a1c1c91..7162f4d 100644 (file)
@@ -43,6 +43,7 @@ class HTTPServerPublisher {
 
   void publishContent(const uint8_t *buf,
                       size_t buffer_size,
+                      std::chrono::milliseconds content_lifetime,
                       const int response_id,
                       bool is_last);
 
index a9f0565..99700f1 100644 (file)
@@ -28,17 +28,21 @@ ContentStore::~ContentStore() {
 }
 
 void ContentStore::insert(const std::shared_ptr<ContentObject> &content_object) {
-  std::unique_lock<std::mutex> lock(cs_mutex_);
-  if (content_store_hash_table_.size() >= max_content_store_size_) {
-    // Evict item
-    content_store_hash_table_.erase(lru_list_.back());
-    lru_list_.pop_back();
-  }
+  // Check if the content can be cached
+  if (content_object->getExpiryTime() > 0) {
+    std::unique_lock<std::mutex> lock(cs_mutex_);
+    if (content_store_hash_table_.size() >= max_content_store_size_) {
+      // Evict item
+      content_store_hash_table_.erase(lru_list_.back());
+      lru_list_.pop_back();
+    }
 
-  // Insert new item
-  lru_list_.push_back(std::cref(content_object->getName()));
-  LRUList::iterator pos = lru_list_.end();
-  content_store_hash_table_[content_object->getName()] = CcnxContentStoreEntry(content_object, pos);
+    // Insert new item
+    lru_list_.push_back(std::cref(content_object->getName()));
+    LRUList::iterator pos = lru_list_.end();
+    content_store_hash_table_[content_object->getName()] = ContentStoreEntry(ObjectTimeEntry(content_object,
+                                                                                             std::chrono::steady_clock::now()), pos);
+  }
 
 }
 
@@ -47,13 +51,20 @@ const std::shared_ptr<ContentObject> &ContentStore::find(const Interest &interes
   ContentStoreHashTable::iterator it = content_store_hash_table_.find(interest.getName());
   if (it != content_store_hash_table_.end()) {
     if (it->second.second != lru_list_.begin()) {
-      // Move element to the top of the LRU list
-      lru_list_.splice(lru_list_.begin(), lru_list_, it->second.second);
+      if (std::chrono::duration_cast<std::chrono::milliseconds>(
+          std::chrono::steady_clock::now().time_since_epoch()).count()
+          < it->second.first.first->getExpiryTime()) {
+        // Move element to the top of the LRU list
+        lru_list_.splice(lru_list_.begin(), lru_list_, it->second.second);
+        return it->second.first.first;
+      } else {
+        // Stale content
+        content_store_hash_table_.erase(interest.getName());
+      }
     }
-    return it->second.first;
-  } else {
-    return empty_reference_;
   }
+
+  return empty_reference_;
 }
 
 void ContentStore::erase(const Name &exact_name) {
index 8a2ed4c..77043d7 100644 (file)
@@ -24,10 +24,11 @@ namespace icnet {
 
 namespace transport {
 
-typedef std::pair<std::shared_ptr<ContentObject>, std::list<std::reference_wrapper<const Name>>::iterator>
-    CcnxContentStoreEntry;
+typedef std::pair<std::shared_ptr<ContentObject>, std::chrono::steady_clock::time_point> ObjectTimeEntry;
+typedef std::pair<ObjectTimeEntry, std::list<std::reference_wrapper<const Name>>::iterator>
+    ContentStoreEntry;
 typedef std::list<std::reference_wrapper<const Name>> LRUList;
-typedef std::unordered_map<Name, CcnxContentStoreEntry> ContentStoreHashTable;
+typedef std::unordered_map<Name, ContentStoreEntry> ContentStoreHashTable;
 
 class ContentStore {
  public:
index 190580f..ec5f665 100644 (file)
@@ -226,7 +226,7 @@ void ProducerSocket::produce(Name name, const uint8_t *buf, size_t buffer_size,
       Name full_name = name;
 
       content_object_segment = std::make_shared<ContentObject>(std::move(full_name.appendSegment(current_segment)));
-      // content_object_segment->setExpiryTime((uint64_t) m_dataFreshness);
+      content_object_segment->setExpiryTime((uint64_t) content_object_expiry_time_);
 
       if (packaged_segments == number_of_segments - 1) {
         content_object_segment->setContent(&buf[bytes_segmented], buffer_size - bytes_segmented);
@@ -277,7 +277,7 @@ void ProducerSocket::produce(Name name, const uint8_t *buf, size_t buffer_size,
           content_object = std::make_shared<ContentObject>(std::move(fullName.appendSegment(current_segment)));
 
       // TODO If we set the throughput will decrease.. to investigate
-      //      content_object->setExpiryTime((uint64_t)m_dataFreshness);
+      content_object->setExpiryTime((uint64_t)content_object_expiry_time_);
 
       if (is_last) {
         content_object->setFinalChunkNumber(current_segment + number_of_segments - packaged_segments - 1);