peek: code modernization and cleanup
Change-Id: I42d706aa02ab03557d708c729f65716c1c2d3494
diff --git a/tools/peek/ndnpeek/main.cpp b/tools/peek/ndnpeek/main.cpp
index 428634a..1586387 100644
--- a/tools/peek/ndnpeek/main.cpp
+++ b/tools/peek/ndnpeek/main.cpp
@@ -37,42 +37,35 @@
namespace po = boost::program_options;
static void
-usage(std::ostream& os, const po::options_description& options)
+usage(std::ostream& os, const std::string& program, const po::options_description& options)
{
- os << "Usage: ndnpeek [options] ndn:/name\n"
- "\n"
- "Fetch one data item matching the name prefix and write it to standard output.\n"
- "\n"
+ os << "Usage: " << program << " [options] ndn:/name\n"
+ << "\n"
+ << "Fetch one data item matching the specified name and write it to the standard output.\n"
<< options;
}
static int
main(int argc, char* argv[])
{
+ std::string progName(argv[0]);
PeekOptions options;
po::options_description genericOptDesc("Generic options");
genericOptDesc.add_options()
- ("help,h", "print help and exit")
- ("payload,p", po::bool_switch(&options.wantPayloadOnly),
- "print payload only, instead of full packet")
- ("timeout,w", po::value<int>(),
- "set timeout (in milliseconds)")
- ("verbose,v", po::bool_switch(&options.isVerbose),
- "turn on verbose output")
+ ("help,h", "print help and exit")
+ ("payload,p", po::bool_switch(&options.wantPayloadOnly), "print payload only, instead of full packet")
+ ("timeout,w", po::value<int>(), "set timeout (in milliseconds)")
+ ("verbose,v", po::bool_switch(&options.isVerbose), "turn on verbose output")
("version,V", "print version and exit")
;
po::options_description interestOptDesc("Interest construction");
interestOptDesc.add_options()
- ("prefix,P", po::bool_switch(&options.canBePrefix),
- "set CanBePrefix")
- ("fresh,f", po::bool_switch(&options.mustBeFresh),
- "set MustBeFresh")
- ("link-file", po::value<std::string>(),
- "set ForwardingHint from a file")
- ("lifetime,l", po::value<int>(),
- "set InterestLifetime (in milliseconds)")
+ ("prefix,P", po::bool_switch(&options.canBePrefix), "set CanBePrefix")
+ ("fresh,f", po::bool_switch(&options.mustBeFresh), "set MustBeFresh")
+ ("link-file", po::value<std::string>(), "set ForwardingHint from a file")
+ ("lifetime,l", po::value<int>(), "set InterestLifetime (in milliseconds)")
;
po::options_description visibleOptDesc;
@@ -99,7 +92,7 @@
}
if (vm.count("help") > 0) {
- usage(std::cout, visibleOptDesc);
+ usage(std::cout, progName, visibleOptDesc);
return 0;
}
@@ -108,12 +101,17 @@
return 0;
}
- if (vm.count("name") > 0) {
+ if (vm.count("name") == 0) {
+ std::cerr << "ERROR: missing name\n\n";
+ usage(std::cerr, progName, visibleOptDesc);
+ return 2;
+ }
+
+ try {
options.name = vm["name"].as<std::string>();
}
- else {
- std::cerr << "ERROR: Interest name is missing" << std::endl;
- usage(std::cerr, visibleOptDesc);
+ catch (const Name::Error& e) {
+ std::cerr << "ERROR: invalid name: " << e.what() << std::endl;
return 2;
}
@@ -122,19 +120,17 @@
options.interestLifetime = time::milliseconds(vm["lifetime"].as<int>());
}
else {
- std::cerr << "ERROR: InterestLifetime must be a non-negative integer" << std::endl;
- usage(std::cerr, visibleOptDesc);
+ std::cerr << "ERROR: lifetime cannot be negative" << std::endl;
return 2;
}
}
if (vm.count("timeout") > 0) {
- if (vm["timeout"].as<int>() > 0) {
+ if (vm["timeout"].as<int>() >= 0) {
options.timeout = time::milliseconds(vm["timeout"].as<int>());
}
else {
- std::cerr << "ERROR: Timeout must be a positive integer" << std::endl;
- usage(std::cerr, visibleOptDesc);
+ std::cerr << "ERROR: timeout cannot be negative" << std::endl;
return 2;
}
}
@@ -142,29 +138,24 @@
if (vm.count("link-file") > 0) {
options.link = io::load<Link>(vm["link-file"].as<std::string>());
if (options.link == nullptr) {
- std::cerr << "ERROR: Cannot read Link object from the specified file" << std::endl;
- usage(std::cerr, visibleOptDesc);
+ std::cerr << "ERROR: cannot read Link object from the specified file" << std::endl;
return 2;
}
}
- Face face;
- NdnPeek program(face, options);
-
try {
+ Face face;
+ NdnPeek program(face, options);
+
program.start();
- face.processEvents(program.getTimeout());
+ face.processEvents();
+
+ return static_cast<int>(program.getResultCode());
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
-
- ResultCode result = program.getResultCode();
- if (result == ResultCode::TIMEOUT && options.isVerbose) {
- std::cerr << "TIMEOUT" << std::endl;
- }
- return static_cast<int>(result);
}
} // namespace peek
diff --git a/tools/peek/ndnpeek/ndnpeek.cpp b/tools/peek/ndnpeek/ndnpeek.cpp
index c371882..8ce23f6 100644
--- a/tools/peek/ndnpeek/ndnpeek.cpp
+++ b/tools/peek/ndnpeek/ndnpeek.cpp
@@ -32,37 +32,28 @@
namespace peek {
NdnPeek::NdnPeek(Face& face, const PeekOptions& options)
- : m_face(face)
- , m_options(options)
- , m_timeout(options.timeout)
- , m_resultCode(ResultCode::TIMEOUT)
+ : m_options(options)
+ , m_face(face)
+ , m_scheduler(m_face.getIoService())
{
- if (m_timeout < 0_ms) {
- m_timeout = m_options.interestLifetime < 0_ms ?
- DEFAULT_INTEREST_LIFETIME : m_options.interestLifetime;
- }
-}
-
-time::milliseconds
-NdnPeek::getTimeout() const
-{
- return m_timeout;
-}
-
-ResultCode
-NdnPeek::getResultCode() const
-{
- return m_resultCode;
}
void
NdnPeek::start()
{
- m_face.expressInterest(createInterest(),
- bind(&NdnPeek::onData, this, _2),
- bind(&NdnPeek::onNack, this, _2),
- nullptr);
- m_expressInterestTime = time::steady_clock::now();
+ m_pendingInterest = m_face.expressInterest(createInterest(),
+ [this] (auto&&, const auto& data) { this->onData(data); },
+ [this] (auto&&, const auto& nack) { this->onNack(nack); },
+ [this] (auto&&) { this->onTimeout(); });
+
+ if (m_options.timeout) {
+ m_timeoutEvent = m_scheduler.schedule(*m_options.timeout, [this] {
+ m_pendingInterest.cancel();
+ onTimeout();
+ });
+ }
+
+ m_sendTime = time::steady_clock::now();
}
Interest
@@ -71,11 +62,11 @@
Interest interest(m_options.name);
interest.setCanBePrefix(m_options.canBePrefix);
interest.setMustBeFresh(m_options.mustBeFresh);
- if (m_options.link != nullptr) {
+ if (m_options.link) {
interest.setForwardingHint(m_options.link->getDelegationList());
}
- if (m_options.interestLifetime >= 0_ms) {
- interest.setInterestLifetime(m_options.interestLifetime);
+ if (m_options.interestLifetime) {
+ interest.setInterestLifetime(*m_options.interestLifetime);
}
if (m_options.isVerbose) {
@@ -89,10 +80,11 @@
NdnPeek::onData(const Data& data)
{
m_resultCode = ResultCode::DATA;
+ m_timeoutEvent.cancel();
if (m_options.isVerbose) {
std::cerr << "DATA: " << data.getName() << "\nRTT: "
- << time::duration_cast<time::milliseconds>(time::steady_clock::now() - m_expressInterestTime).count()
+ << time::duration_cast<time::milliseconds>(time::steady_clock::now() - m_sendTime).count()
<< " ms" << std::endl;
}
@@ -110,11 +102,12 @@
NdnPeek::onNack(const lp::Nack& nack)
{
m_resultCode = ResultCode::NACK;
- lp::NackHeader header = nack.getHeader();
+ m_timeoutEvent.cancel();
+ lp::NackHeader header = nack.getHeader();
if (m_options.isVerbose) {
std::cerr << "NACK: " << header.getReason() << "\nRTT: "
- << time::duration_cast<time::milliseconds>(time::steady_clock::now() - m_expressInterestTime).count()
+ << time::duration_cast<time::milliseconds>(time::steady_clock::now() - m_sendTime).count()
<< " ms" << std::endl;
}
@@ -127,5 +120,16 @@
}
}
+void
+NdnPeek::onTimeout()
+{
+ m_resultCode = ResultCode::TIMEOUT;
+ m_timeoutEvent.cancel();
+
+ if (m_options.isVerbose) {
+ std::cerr << "TIMEOUT" << std::endl;
+ }
+}
+
} // namespace peek
} // namespace ndn
diff --git a/tools/peek/ndnpeek/ndnpeek.hpp b/tools/peek/ndnpeek/ndnpeek.hpp
index 4eac8d3..a544b37 100644
--- a/tools/peek/ndnpeek/ndnpeek.hpp
+++ b/tools/peek/ndnpeek/ndnpeek.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,9 @@
#define NDN_TOOLS_NDNPEEK_NDNPEEK_HPP
#include "core/common.hpp"
+
#include <ndn-cxx/link.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
namespace ndn {
namespace peek {
@@ -41,23 +43,23 @@
struct PeekOptions
{
// Interest construction options
- std::string name;
+ Name name;
bool canBePrefix = false;
bool mustBeFresh = false;
shared_ptr<Link> link;
- time::milliseconds interestLifetime = -1_ms;
+ optional<time::milliseconds> interestLifetime;
// output behavior options
bool isVerbose = false;
- time::milliseconds timeout = -1_ms;
bool wantPayloadOnly = false;
+ optional<time::milliseconds> timeout;
};
enum class ResultCode {
- NONE = -1,
+ UNKNOWN = 1,
DATA = 0,
NACK = 4,
- TIMEOUT = 3
+ TIMEOUT = 3,
};
class NdnPeek : boost::noncopyable
@@ -66,16 +68,13 @@
NdnPeek(Face& face, const PeekOptions& options);
/**
- * @return the timeout
- */
- time::milliseconds
- getTimeout() const;
-
- /**
- * @return the result of Peek execution
+ * @return the result of NdnPeek execution
*/
ResultCode
- getResultCode() const;
+ getResultCode() const
+ {
+ return m_resultCode;
+ }
/**
* @brief express the Interest
@@ -100,12 +99,20 @@
void
onNack(const lp::Nack& nack);
+ /**
+ * @brief called when the Interest times out
+ */
+ void
+ onTimeout();
+
private:
- Face& m_face;
const PeekOptions& m_options;
- time::steady_clock::TimePoint m_expressInterestTime;
- time::milliseconds m_timeout;
- ResultCode m_resultCode;
+ Face& m_face;
+ Scheduler m_scheduler;
+ time::steady_clock::TimePoint m_sendTime;
+ ScopedPendingInterestHandle m_pendingInterest;
+ scheduler::ScopedEventId m_timeoutEvent;
+ ResultCode m_resultCode = ResultCode::UNKNOWN;
};
} // namespace peek