37 const time::milliseconds Readvertise::RETRY_DELAY_MIN = 50_s;
38 const time::milliseconds Readvertise::RETRY_DELAY_MAX = 1_h;
40 static time::milliseconds
43 std::uniform_int_distribution<> dist(-5, 5);
45 return std::max(newTime, 0_ms);
49 unique_ptr<ReadvertisePolicy> policy,
50 unique_ptr<ReadvertiseDestination> destination)
51 : m_policy(std::
move(policy))
52 , m_destination(std::
move(destination))
54 m_addRouteConn = rib.
afterAddRoute.connect([
this] (
const auto& r) { this->afterAddRoute(r); });
55 m_removeRouteConn = rib.
beforeRemoveRoute.connect([
this] (
const auto& r) { this->beforeRemoveRoute(r); });
57 m_destination->afterAvailabilityChange.connect([
this] (
bool isAvailable) {
59 this->afterDestinationAvailable();
62 this->afterDestinationUnavailable();
68 Readvertise::afterAddRoute(
const RibRouteRef& ribRoute)
70 optional<ReadvertiseAction> action = m_policy->handleNewRoute(ribRoute);
73 ',' << ribRoute.
route->origin <<
") not-readvertising");
77 ReadvertisedRouteContainer::iterator rrIt;
79 std::tie(rrIt, isNew) = m_rrs.emplace(action->prefix);
81 if (!isNew && rrIt->signer != action->signer) {
83 ',' << ribRoute.
route->origin <<
") readvertising-as " << action->prefix <<
84 " old-signer " << rrIt->signer <<
" new-signer " << action->signer);
86 rrIt->signer = action->signer;
88 RouteRrIndex::iterator indexIt;
89 std::tie(indexIt, isNew) = m_routeToRr.emplace(ribRoute, rrIt);
92 if (rrIt->nRibRoutes++ > 0) {
94 ',' << ribRoute.
route->origin <<
") already-readvertised-as " << action->prefix);
99 ',' << ribRoute.
route->origin <<
") readvertising-as " << action->prefix <<
100 " signer " << action->signer);
101 rrIt->retryDelay = RETRY_DELAY_MIN;
102 this->advertise(rrIt);
106 Readvertise::beforeRemoveRoute(
const RibRouteRef& ribRoute)
108 auto indexIt = m_routeToRr.find(ribRoute);
109 if (indexIt == m_routeToRr.end()) {
110 NFD_LOG_DEBUG(
"remove-route " << ribRoute.entry->getName() <<
'(' << ribRoute.route->faceId <<
111 ',' << ribRoute.route->origin <<
") not-readvertised");
115 auto rrIt = indexIt->second;
116 m_routeToRr.erase(indexIt);
118 if (--rrIt->nRibRoutes > 0) {
119 NFD_LOG_DEBUG(
"remove-route " << ribRoute.entry->getName() <<
'(' << ribRoute.route->faceId <<
120 ',' << ribRoute.route->origin <<
") needed-by " << rrIt->nRibRoutes);
124 rrIt->retryDelay = RETRY_DELAY_MIN;
125 this->withdraw(rrIt);
129 Readvertise::afterDestinationAvailable()
131 for (
auto rrIt = m_rrs.begin(); rrIt != m_rrs.end(); ++rrIt) {
132 rrIt->retryDelay = RETRY_DELAY_MIN;
133 this->advertise(rrIt);
138 Readvertise::afterDestinationUnavailable()
140 for (
auto rrIt = m_rrs.begin(); rrIt != m_rrs.end();) {
141 if (rrIt->nRibRoutes > 0) {
142 rrIt->retryEvt.cancel();
146 rrIt = m_rrs.erase(rrIt);
152 Readvertise::advertise(ReadvertisedRouteContainer::iterator rrIt)
154 BOOST_ASSERT(rrIt->nRibRoutes > 0);
156 if (!m_destination->isAvailable()) {
157 NFD_LOG_DEBUG(
"advertise " << rrIt->prefix <<
" destination-unavailable");
161 m_destination->advertise(*rrIt,
164 rrIt->retryDelay = RETRY_DELAY_MIN;
166 [=] { advertise(rrIt); });
168 [=] (
const std::string& msg) {
169 NFD_LOG_DEBUG(
"advertise " << rrIt->prefix <<
" failure " << msg);
170 rrIt->retryDelay = std::min(RETRY_DELAY_MAX, rrIt->retryDelay * 2);
172 [=] { advertise(rrIt); });
177 Readvertise::withdraw(ReadvertisedRouteContainer::iterator rrIt)
179 BOOST_ASSERT(rrIt->nRibRoutes == 0);
181 if (!m_destination->isAvailable()) {
182 NFD_LOG_DEBUG(
"withdraw " << rrIt->prefix <<
" destination-unavailable");
187 m_destination->withdraw(*rrIt,
192 [=] (
const std::string& msg) {
193 NFD_LOG_DEBUG(
"withdraw " << rrIt->prefix <<
" failure " << msg);
194 rrIt->retryDelay = std::min(RETRY_DELAY_MAX, rrIt->retryDelay * 2);
196 [=] { withdraw(rrIt); });