Skip to content

Commit

Permalink
Add ASF measurement lifetime as strategy parameter
Browse files Browse the repository at this point in the history
Refs: #5332
Change-Id: Iff42ca0870d4263f0ad8757a67b87e52dbfff9f5
  • Loading branch information
awlane committed Oct 24, 2024
1 parent a1480a7 commit ee97f53
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 17 deletions.
8 changes: 4 additions & 4 deletions daemon/fw/asf-measurements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ NamespaceInfo::getOrCreateFaceInfo(FaceId faceId)
void
NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, FaceId faceId)
{
info.m_measurementExpiration = getScheduler().schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
info.m_measurementExpiration = getScheduler().schedule(m_measurementLifetime,
[=] { m_fiMap.erase(faceId); });
}

Expand Down Expand Up @@ -105,7 +105,7 @@ AsfMeasurements::getNamespaceInfo(const Name& prefix)
// Set or update entry lifetime
extendLifetime(*me);

NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>(m_rttEstimatorOpts).first;
NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>(m_rttEstimatorOpts, m_measurementsLifetime).first;
BOOST_ASSERT(info != nullptr);
return info;
}
Expand All @@ -129,15 +129,15 @@ AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Name
// Set or update entry lifetime
extendLifetime(*me);

NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>(m_rttEstimatorOpts).first;
NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>(m_rttEstimatorOpts, m_measurementsLifetime).first;
BOOST_ASSERT(info != nullptr);
return *info;
}

void
AsfMeasurements::extendLifetime(measurements::Entry& me)
{
m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
m_measurements.extendLifetime(me, m_measurementsLifetime);
}

} // namespace nfd::fw::asf
21 changes: 19 additions & 2 deletions daemon/fw/asf-measurements.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ class NamespaceInfo final : public StrategyInfo
}

explicit
NamespaceInfo(shared_ptr<const ndn::util::RttEstimator::Options> opts)
NamespaceInfo(shared_ptr<const ndn::util::RttEstimator::Options> opts, time::milliseconds measurementLifetime)
: m_rttEstimatorOpts(std::move(opts))
, m_measurementLifetime(measurementLifetime)
{
}

Expand Down Expand Up @@ -173,6 +174,7 @@ class NamespaceInfo final : public StrategyInfo
private:
std::unordered_map<FaceId, FaceInfo> m_fiMap;
shared_ptr<const ndn::util::RttEstimator::Options> m_rttEstimatorOpts;
time::milliseconds m_measurementLifetime;
bool m_isProbingDue = false;
bool m_isFirstProbeScheduled = false;
};
Expand Down Expand Up @@ -201,14 +203,29 @@ class AsfMeasurements : noncopyable
NamespaceInfo&
getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Name& prefix);

void
setMeasurementsLifetime(time::milliseconds measurementsLifetime)
{
// Measurement lifetime should not expire as soon as it is configured
BOOST_ASSERT(measurementsLifetime > 0_ms);
m_measurementsLifetime = measurementsLifetime;
}

time::milliseconds
getMeasurementsLifetime() const
{
return m_measurementsLifetime;
}

private:
void
extendLifetime(measurements::Entry& me);

public:
static constexpr time::microseconds MEASUREMENTS_LIFETIME = 5_min;
static constexpr time::milliseconds DEFAULT_MEASUREMENTS_LIFETIME = 5_min;

private:
time::milliseconds m_measurementsLifetime = DEFAULT_MEASUREMENTS_LIFETIME;
MeasurementsAccessor& m_measurements;
shared_ptr<const ndn::util::RttEstimator::Options> m_rttEstimatorOpts;
};
Expand Down
2 changes: 1 addition & 1 deletion daemon/fw/asf-probing-module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

namespace nfd::fw::asf {

static_assert(ProbingModule::DEFAULT_PROBING_INTERVAL < AsfMeasurements::MEASUREMENTS_LIFETIME);
static_assert(ProbingModule::DEFAULT_PROBING_INTERVAL < AsfMeasurements::DEFAULT_MEASUREMENTS_LIFETIME);

ProbingModule::ProbingModule(AsfMeasurements& measurements)
: m_probingInterval(DEFAULT_PROBING_INTERVAL)
Expand Down
12 changes: 11 additions & 1 deletion daemon/fw/asf-strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "asf-strategy.hpp"
#include "algorithm.hpp"
#include "common/logger.hpp"
#include <boost/lexical_cast.hpp>

namespace nfd::fw::asf {

Expand All @@ -48,12 +49,21 @@ AsfStrategy::AsfStrategy(Forwarder& forwarder, const Name& name)
m_probing.getProbingInterval().count());
m_probing.setProbingInterval(time::milliseconds(probingInterval));
m_nMaxTimeouts = params.getOrDefault<size_t>("max-timeouts", m_nMaxTimeouts);
auto measurementsLifetime = time::milliseconds(params.getOrDefault<time::milliseconds::rep>("measurements-lifetime",
AsfMeasurements::DEFAULT_MEASUREMENTS_LIFETIME.count()));
if (measurementsLifetime <= m_probing.getProbingInterval()) {
NDN_THROW(std::invalid_argument("Measurements lifetime (" + boost::lexical_cast<std::string>(measurementsLifetime) +
") should be greater than the probing interval of " +
boost::lexical_cast<std::string>(m_probing.getProbingInterval())));
}
m_measurements.setMeasurementsLifetime(measurementsLifetime);

this->setInstanceName(makeInstanceName(name, getStrategyName()));

NDN_LOG_DEBUG(*m_retxSuppression);
NFD_LOG_DEBUG("probing-interval=" << m_probing.getProbingInterval()
<< " max-timeouts=" << m_nMaxTimeouts);
<< " max-timeouts=" << m_nMaxTimeouts
<< " measurements-lifetime=" << m_measurements.getMeasurementsLifetime());
}

const Name&
Expand Down
4 changes: 1 addition & 3 deletions daemon/fw/asf-strategy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ class AsfStrategy : public Strategy, public ProcessNackTraits<AsfStrategy>
void
sendNoRouteNack(Face& face, const shared_ptr<pit::Entry>& pitEntry);

private:
AsfMeasurements m_measurements{getMeasurements()};

NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
struct FaceStatsForwardingCompare
{
Expand All @@ -96,6 +93,7 @@ class AsfStrategy : public Strategy, public ProcessNackTraits<AsfStrategy>
};
using FaceStatsForwardingSet = std::set<FaceStats, FaceStatsForwardingCompare>;

AsfMeasurements m_measurements{getMeasurements()};
std::unique_ptr<RetxSuppressionExponential> m_retxSuppression;
ProbingModule m_probing{m_measurements};
size_t m_nMaxTimeouts = 3;
Expand Down
15 changes: 13 additions & 2 deletions docs/manpages/nfd-asf-strategy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ Options
integer). Smaller values will result in higher overhead but faster reaction.
The default value is 1 minute and the minimum value is 1 second.

.. option:: measurements-lifetime <LIFETIME>

This optional parameter tells ASF how long to retain NamespaceInfo and FaceInfo
measurements if they are not actively updated. If not specified, this value defaults
to 5 minutes. This value is specified in (non-negative integer) milliseconds and must
be greater than the probing interval, as otherwise there is negligible benefit gained
from the additional traffic generated by ASF.

.. option:: max-timeouts <TIMEOUTS>

This optional parameter makes ASF switch to another appropriate face (if available)
Expand All @@ -45,8 +53,11 @@ Examples
``nfdc strategy set prefix /ndn strategy /localhost/nfd/strategy/asf/v=5/max-timeouts~5``
Set the maximum number of timeouts to 5.

``nfdc strategy set prefix /ndn strategy /localhost/nfd/strategy/asf/v=5/probing-interval~30000/max-timeouts~2``
Set the probing interval to 30 seconds and the maximum number of timeouts to 2.
``nfdc strategy set prefix /ndn strategy /localhost/nfd/strategy/asf/v=5/measurements-lifetime~120000``
Set the maximum measurement lifetime to 2 minutes.

``nfdc strategy set prefix /ndn strategy /localhost/nfd/strategy/asf/v=5/probing-interval~30000/max-timeouts~2/measurements-lifetime~120000``
Set the probing interval to 30 seconds, the maximum number of timeouts to 2, and the maximum measurement lifetime to 2 minutes.

``nfdc strategy set prefix /ndn strategy /localhost/nfd/strategy/asf/v=5/retx-suppression-multiplier~2.5/probing-interval~45000``
Set the retransmission suppression multiplier to 2.5 and the probing interval
Expand Down
6 changes: 3 additions & 3 deletions tests/daemon/fw/asf-measurements.t.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -75,14 +75,14 @@ BOOST_FIXTURE_TEST_CASE(FaceInfo, GlobalIoTimeFixture)
BOOST_FIXTURE_TEST_CASE(NamespaceInfo, GlobalIoTimeFixture)
{
using fw::asf::NamespaceInfo;
NamespaceInfo info(nullptr);
NamespaceInfo info(nullptr, fw::asf::AsfMeasurements::DEFAULT_MEASUREMENTS_LIFETIME);

BOOST_CHECK(info.getFaceInfo(1234) == nullptr);

auto& faceInfo = info.getOrCreateFaceInfo(1234);
BOOST_CHECK(info.getFaceInfo(1234) == &faceInfo);

this->advanceClocks(fw::asf::AsfMeasurements::MEASUREMENTS_LIFETIME + 1_s);
this->advanceClocks(fw::asf::AsfMeasurements::DEFAULT_MEASUREMENTS_LIFETIME + 1_s);
BOOST_CHECK(info.getFaceInfo(1234) == nullptr); // expired
}

Expand Down
26 changes: 25 additions & 1 deletion tests/daemon/fw/asf-strategy.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,18 +561,33 @@ BOOST_AUTO_TEST_CASE(Parameters)
auto strategy = checkValidity("", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
BOOST_TEST(strategy->m_nMaxTimeouts == 3);
strategy = checkValidity("/probing-interval~30000/max-timeouts~5", true);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
strategy = checkValidity("/probing-interval~30000/max-timeouts~5/measurements-lifetime~120000", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
BOOST_TEST(strategy->m_nMaxTimeouts == 5);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
strategy = checkValidity("/max-timeouts~5/probing-interval~30000", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
BOOST_TEST(strategy->m_nMaxTimeouts == 5);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
strategy = checkValidity("/max-timeouts~5/measurements-lifetime~120000", true);
BOOST_TEST(strategy->m_nMaxTimeouts == 5);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
strategy = checkValidity("/probing-interval~30000/measurements-lifetime~120000", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
strategy = checkValidity("/probing-interval~1000", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 1_s);
BOOST_TEST(strategy->m_nMaxTimeouts == 3);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
strategy = checkValidity("/max-timeouts~0", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
BOOST_TEST(strategy->m_nMaxTimeouts == 0);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
strategy = checkValidity("/measurements-lifetime~120000", true);
BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
BOOST_TEST(strategy->m_nMaxTimeouts == 3);
BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
BOOST_TEST(strategy->m_retxSuppression->m_initialInterval == fw::RetxSuppressionExponential::DEFAULT_INITIAL_INTERVAL);
BOOST_TEST(strategy->m_retxSuppression->m_maxInterval == fw::RetxSuppressionExponential::DEFAULT_MAX_INTERVAL);
BOOST_TEST(strategy->m_retxSuppression->m_multiplier == fw::RetxSuppressionExponential::DEFAULT_MULTIPLIER);
Expand All @@ -585,6 +600,15 @@ BOOST_AUTO_TEST_CASE(Parameters)
checkValidity("/max-timeouts~1/probing-interval~-30000", false);
checkValidity("/probing-interval~foo", false);
checkValidity("/max-timeouts~1~2", false);
checkValidity("/measurements-lifetime~1000", false); //Minimum is 60s by default
//Measurement lifetime must be greater than probing interval
checkValidity("/measurements-lifetime~1000/probing-interval~30000", false);
checkValidity("/measurements-lifetime~-120000", false);
checkValidity("/measurements-lifetime~ -120000", false);
checkValidity("/measurements-lifetime~0-120000", false);
checkValidity("/max-timeouts~1/measurements-lifetime~-120000", false);
checkValidity("/probing-interval~30000/measurements-lifetime~-120000", false);
checkValidity("/max-timeouts~1/probing-interval~30000/measurements-lifetime~-120000", false);
}

BOOST_AUTO_TEST_CASE(FaceRankingForForwarding)
Expand Down

0 comments on commit ee97f53

Please sign in to comment.