server: add timeout before shutdown to avoid lost Data packets
refs #4626
Change-Id: Idc6d90fdd60a3db48364ee0afe20e7802da16d32
diff --git a/src/ndn-traffic-server.cpp b/src/ndn-traffic-server.cpp
index e7a0cb6..b58a880 100644
--- a/src/ndn-traffic-server.cpp
+++ b/src/ndn-traffic-server.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2014-2015 University of Arizona.
+/*
+ * Copyright (C) 2014-2018 Arizona Board of Regents.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,24 +18,25 @@
* Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
*/
-#include <cctype>
-#include <cstdlib>
-#include <fstream>
-#include <string>
-#include <unistd.h>
-#include <vector>
+#include "logger.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/signing-info.hpp>
+#include <ndn-cxx/util/backports.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/security/signing-info.hpp>
-#include <ndn-cxx/util/backports.hpp>
-
-#include "logger.hpp"
+#include <cctype>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <unistd.h>
+#include <vector>
namespace ndn {
@@ -54,6 +55,7 @@
, m_contentDelay(time::milliseconds(-1))
, m_instanceId(to_string(std::rand()))
, m_face(m_ioService)
+ , m_scheduler(m_ioService)
{
}
@@ -75,19 +77,25 @@
{
std::stringstream detail;
- if (!m_name.empty())
+ if (!m_name.empty()) {
detail << "Name=" << m_name << ", ";
- if (m_contentType >= 0)
+ }
+ if (m_contentType >= 0) {
detail << "ContentType=" << to_string(m_contentType) << ", ";
- if (m_freshnessPeriod >= time::milliseconds(0))
+ }
+ if (m_freshnessPeriod >= time::milliseconds(0)) {
detail << "FreshnessPeriod=" <<
to_string(static_cast<int>(m_freshnessPeriod.count())) << ", ";
- if (m_contentBytes >= 0)
+ }
+ if (m_contentBytes >= 0) {
detail << "ContentBytes=" << to_string(m_contentBytes) << ", ";
- if (m_contentDelay >= time::milliseconds(0))
+ }
+ if (m_contentDelay >= time::milliseconds(0)) {
detail << "ContentDelay=" << to_string(m_contentDelay.count()) << ", ";
- if (!m_content.empty())
+ }
+ if (!m_content.empty()) {
detail << "Content=" << m_content << ", ";
+ }
detail << "SigningInfo=" << m_signingInfo;
logger.log(detail.str(), false, false);
@@ -204,8 +212,9 @@
void
setMaximumInterests(int maximumInterests)
{
- if (maximumInterests < 0)
+ if (maximumInterests < 0) {
usage();
+ }
m_nMaximumInterests = maximumInterests;
}
@@ -218,8 +227,9 @@
void
setContentDelay(int contentDelay)
{
- if (contentDelay < 0)
+ if (contentDelay < 0) {
usage();
+ }
m_contentDelay = time::milliseconds(contentDelay);
}
@@ -256,16 +266,16 @@
m_logger.log("Total Interests Received = " +
to_string(m_nInterestsReceived), false, true);
- if (m_nInterestsReceived < m_nMaximumInterests)
+ if (m_nInterestsReceived < m_nMaximumInterests) {
m_hasError = true;
+ }
- for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
- {
- m_logger.log("\nTraffic Pattern Type #" + to_string(patternId + 1), false, true);
- m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
- m_logger.log("Total Interests Received = " + to_string(
- m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
- }
+ for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
+ m_logger.log("\nTraffic Pattern Type #" + to_string(patternId + 1), false, true);
+ m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
+ m_logger.log("Total Interests Received = " + to_string(
+ m_trafficPatterns[patternId].m_nInterestsReceived) + "\n", false, true);
+ }
}
bool
@@ -282,98 +292,87 @@
m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);
patternFile.open(m_configurationFile.c_str());
- if (patternFile.is_open())
- {
- int lineNumber = 0;
- while (getline(patternFile, patternLine))
- {
- lineNumber++;
- if (std::isalpha(patternLine[0]))
- {
- DataTrafficConfiguration dataData;
- bool shouldSkipLine = false;
- if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
- {
- while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
- {
- lineNumber++;
- if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber))
- {
- shouldSkipLine = true;
- break;
- }
- }
- lineNumber++;
- }
- else
- shouldSkipLine = true;
- if (!shouldSkipLine)
- {
- if (dataData.checkTrafficDetailCorrectness())
- m_trafficPatterns.push_back(dataData);
- }
+ if (patternFile.is_open()) {
+ int lineNumber = 0;
+ while (getline(patternFile, patternLine)) {
+ lineNumber++;
+ if (std::isalpha(patternLine[0])) {
+ DataTrafficConfiguration dataData;
+ bool shouldSkipLine = false;
+ if (dataData.processConfigurationDetail(patternLine, m_logger, lineNumber)) {
+ while (getline(patternFile, patternLine) && std::isalpha(patternLine[0])) {
+ lineNumber++;
+ if (!dataData.processConfigurationDetail(patternLine, m_logger, lineNumber)) {
+ shouldSkipLine = true;
+ break;
}
+ }
+ lineNumber++;
}
- patternFile.close();
-
- if (!checkTrafficPatternCorrectness())
- {
- m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper - " +
- m_configurationFile, false, true);
- m_logger.shutdownLogger();
- exit(EXIT_FAILURE);
+ else {
+ shouldSkipLine = true;
}
-
- m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
- for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
- {
- m_logger.log("Traffic Pattern Type #" +
- to_string(patternId + 1), false, false);
- m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
- m_logger.log("", false, false);
+ if (!shouldSkipLine) {
+ if (dataData.checkTrafficDetailCorrectness()) {
+ m_trafficPatterns.push_back(dataData);
+ }
}
+ }
}
- else
- {
- m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
- m_configurationFile, false, true);
+ patternFile.close();
+
+ if (!checkTrafficPatternCorrectness()) {
+ m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper - " +
+ m_configurationFile, false, true);
m_logger.shutdownLogger();
exit(EXIT_FAILURE);
}
+
+ m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
+ for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
+ m_logger.log("Traffic Pattern Type #" +
+ to_string(patternId + 1), false, false);
+ m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
+ m_logger.log("", false, false);
+ }
+ }
+ else {
+ m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
+ m_configurationFile, false, true);
+ m_logger.shutdownLogger();
+ exit(EXIT_FAILURE);
+ }
}
void
initializeTrafficConfiguration()
{
- if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
- {
- if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
- {
- parseConfigurationFile();
- }
- else
- {
- m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
- m_configurationFile, false, true);
- m_logger.shutdownLogger();
- exit(EXIT_FAILURE);
- }
+ if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile))) {
+ if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile))) {
+ parseConfigurationFile();
}
- else
- {
- m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
- m_configurationFile, false, true);
+ else {
+ m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
+ m_configurationFile, false, true);
m_logger.shutdownLogger();
exit(EXIT_FAILURE);
}
+ }
+ else {
+ m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
+ m_configurationFile, false, true);
+ m_logger.shutdownLogger();
+ exit(EXIT_FAILURE);
+ }
}
static std::string
getRandomByteString(std::size_t randomSize)
{
std::string randomString;
- for (std::size_t i = 0; i < randomSize; i++)
+ for (std::size_t i = 0; i < randomSize; i++) {
randomString += static_cast<char>(std::rand() % 128);
+ }
return randomString;
}
@@ -382,50 +381,50 @@
{
auto& pattern = m_trafficPatterns[patternId];
- if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests)
- {
- Data data(interest.getName());
+ if (m_nMaximumInterests < 0 || m_nInterestsReceived < m_nMaximumInterests) {
+ Data data(interest.getName());
- if (pattern.m_contentType >= 0)
- data.setContentType(pattern.m_contentType);
+ if (pattern.m_contentType >= 0)
+ data.setContentType(pattern.m_contentType);
- if (pattern.m_freshnessPeriod >= time::milliseconds(0))
- data.setFreshnessPeriod(pattern.m_freshnessPeriod);
+ if (pattern.m_freshnessPeriod >= time::milliseconds(0))
+ data.setFreshnessPeriod(pattern.m_freshnessPeriod);
- std::string content;
- if (pattern.m_contentBytes >= 0)
- content = getRandomByteString(pattern.m_contentBytes);
- if (!pattern.m_content.empty())
- content = pattern.m_content;
+ std::string content;
+ if (pattern.m_contentBytes >= 0)
+ content = getRandomByteString(pattern.m_contentBytes);
+ if (!pattern.m_content.empty())
+ content = pattern.m_content;
- data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
- m_keyChain.sign(data, pattern.m_signingInfo);
+ data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.length());
+ m_keyChain.sign(data, pattern.m_signingInfo);
- m_nInterestsReceived++;
- pattern.m_nInterestsReceived++;
+ m_nInterestsReceived++;
+ pattern.m_nInterestsReceived++;
- if (!m_hasQuietLogging) {
- std::string logLine =
- "Interest Received - PatternType=" + to_string(patternId + 1) +
- ", GlobalID=" + to_string(m_nInterestsReceived) +
- ", LocalID=" + to_string(pattern.m_nInterestsReceived) +
- ", Name=" + pattern.m_name;
- m_logger.log(logLine, true, false);
- }
-
- if (pattern.m_contentDelay > time::milliseconds(-1))
- usleep(pattern.m_contentDelay.count() * 1000);
- if (m_contentDelay > time::milliseconds(-1))
- usleep(m_contentDelay.count() * 1000);
- m_face.put(data);
+ if (!m_hasQuietLogging) {
+ std::string logLine =
+ "Interest Received - PatternType=" + to_string(patternId + 1) +
+ ", GlobalID=" + to_string(m_nInterestsReceived) +
+ ", LocalID=" + to_string(pattern.m_nInterestsReceived) +
+ ", Name=" + pattern.m_name;
+ m_logger.log(logLine, true, false);
}
- if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests)
- {
- logStatistics();
- m_logger.shutdownLogger();
- m_face.shutdown();
- m_ioService.stop();
- }
+
+ if (pattern.m_contentDelay > time::milliseconds(-1))
+ usleep(pattern.m_contentDelay.count() * 1000);
+ if (m_contentDelay > time::milliseconds(-1))
+ usleep(m_contentDelay.count() * 1000);
+ m_face.put(data);
+ }
+ if (m_nMaximumInterests >= 0 && m_nInterestsReceived == m_nMaximumInterests) {
+ logStatistics();
+ m_scheduler.scheduleEvent(2_s, [this] {
+ m_logger.shutdownLogger();
+ m_face.shutdown();
+ m_ioService.stop();
+ });
+ }
}
void
@@ -437,11 +436,10 @@
m_logger.log(logLine, true, true);
m_nRegistrationsFailed++;
- if (m_nRegistrationsFailed == m_trafficPatterns.size())
- {
- m_hasError = true;
- signalHandler();
- }
+ if (m_nRegistrationsFailed == m_trafficPatterns.size()) {
+ m_hasError = true;
+ signalHandler();
+ }
}
void
@@ -452,17 +450,17 @@
m_logger.initializeLog(m_instanceId);
initializeTrafficConfiguration();
- if (m_nMaximumInterests == 0)
- {
- logStatistics();
- m_logger.shutdownLogger();
- return;
- }
+ if (m_nMaximumInterests == 0) {
+ logStatistics();
+ m_logger.shutdownLogger();
+ return;
+ }
- for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
+ for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
m_face.setInterestFilter(m_trafficPatterns[patternId].m_name,
bind(&NdnTrafficServer::onInterest, this, _1, _2, patternId),
bind(&NdnTrafficServer::onRegisterFailed, this, _1, _2, patternId));
+ }
try {
m_face.processEvents();
@@ -490,6 +488,7 @@
boost::asio::io_service m_ioService;
Face m_face;
+ util::scheduler::Scheduler m_scheduler;
std::vector<DataTrafficConfiguration> m_trafficPatterns;
};
@@ -525,11 +524,12 @@
argc -= optind;
argv += optind;
- if (!argc)
+ if (!argc) {
server.usage();
+ }
server.setConfigurationFile(argv[0]);
server.run();
return server.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
-}
\ No newline at end of file
+}