在看NDN的默认转发策略BestRoute Strategy中提到了指数退避算法,回忆了一下,即为:

在一个共享信道的情况下,当网络上的节点在发生冲突时,每个节点节点等待一定的时间后重新发送。在二进制指数退避算法中,等待时间随着以二为底的指数增长。如果重试失败,那么下次的等待时间将会是上次的等待时间二倍。如果重试次数大于最大重试次数,那么包将从包队列中去除。

BestRoute Strategy:把Interest发给具有最小cost的下一跳,没收到要重传时选择次小cost的下一跳

This strategy forwards a new Interest to the lowest-cost nexthop (except downstream). After that, if consumer retransmits the Interest (and is not suppressed according to exponential backoff algorithm), the strategy forwards the Interest again to the lowest-cost nexthop (except downstream) that is not previously used. If all nexthops have been used, the strategy starts over with the first nexthop.

This strategy returns Nack to all downstreams with reason NoRoute if there is no usable nexthop, which may be caused by: (a) the FIB entry contains no nexthop; (b) the FIB nexthop happens to be the sole downstream; (c) the FIB nexthops violate scope.

This strategy returns Nack to all downstreams if all upstreams have returned Nacks. The reason of the sent Nack equals the least severe reason among received Nacks.

    1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */26 #include "best-route-strategy2.hpp"27 #include "core/logger.hpp"28 29 namespace nfd {30 namespace fw {31 32 NFD_LOG_INIT("BestRouteStrategy2");33 34 const Name BestRouteStrategy2::STRATEGY_NAME("ndn:/localhost/nfd/strategy/best-route/%FD%04");35 NFD_REGISTER_STRATEGY(BestRouteStrategy2);36 37 const time::milliseconds BestRouteStrategy2::RETX_SUPPRESSION_INITIAL(10);38 const time::milliseconds BestRouteStrategy2::RETX_SUPPRESSION_MAX(250);39 40 BestRouteStrategy2::BestRouteStrategy2(Forwarder& forwarder, const Name& name)41   : Strategy(forwarder, name)42   , m_retxSuppression(RETX_SUPPRESSION_INITIAL,43                       RetxSuppressionExponential::DEFAULT_MULTIPLIER,44                       RETX_SUPPRESSION_MAX)45 {46 }47 55 static inline bool56 predicate_NextHop_eligible(const shared_ptr<pit::Entry>& pitEntry,57   const fib::NextHop& nexthop, FaceId currentDownstream,58   bool wantUnused = false,59   time::steady_clock::TimePoint now = time::steady_clock::TimePoint::min())60 {61   shared_ptr<Face> upstream = nexthop.getFace();62 63   // upstream is current downstream64   if (upstream->getId() == currentDownstream)65     return false;66 67   // forwarding would violate scope68   if (pitEntry->violatesScope(*upstream))69     return false;70 71   if (wantUnused) {72     // NextHop must not have unexpired OutRecord73     pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*upstream);74     if (outRecord != pitEntry->getOutRecords().end() &&75         outRecord->getExpiry() > now) {76       return false;77     }78   }79 80   return true;81 }82 86 static inline fib::NextHopList::const_iterator87 findEligibleNextHopWithEarliestOutRecord(const shared_ptr<pit::Entry>& pitEntry,88                                          const fib::NextHopList& nexthops,89                                          FaceId currentDownstream)90 {91   fib::NextHopList::const_iterator found = nexthops.end();92   time::steady_clock::TimePoint earliestRenewed = time::steady_clock::TimePoint::max();93   for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {94     if (!predicate_NextHop_eligible(pitEntry, *it, currentDownstream))95       continue;96     pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*it->getFace());97     BOOST_ASSERT(outRecord != pitEntry->getOutRecords().end());98     if (outRecord->getLastRenewed() < earliestRenewed) {99       found = it;100       earliestRenewed = outRecord->getLastRenewed();101     }102   }103   return found;104 }105 106 void107 BestRouteStrategy2::afterReceiveInterest(const Face& inFace,108                                          const Interest& interest,109                                          shared_ptr<fib::Entry> fibEntry,110                                          shared_ptr<pit::Entry> pitEntry)111 {112   const fib::NextHopList& nexthops = fibEntry->getNextHops();113   fib::NextHopList::const_iterator it = nexthops.end();114 115   RetxSuppression::Result suppression = m_retxSuppression.decide(inFace, interest, *pitEntry);116   if (suppression == RetxSuppression::NEW) {117     // forward to nexthop with lowest cost except downstream118     it = std::find_if(nexthops.begin(), nexthops.end(),119       bind(&predicate_NextHop_eligible, pitEntry, _1, inFace.getId(),120            false, time::steady_clock::TimePoint::min()));121 122     if (it == nexthops.end()) {123       NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");124 125       lp::NackHeader nackHeader;126       nackHeader.setReason(lp::NackReason::NO_ROUTE);127       this->sendNack(pitEntry, inFace, nackHeader);128 129       this->rejectPendingInterest(pitEntry);130       return;131     }132 133     shared_ptr<Face> outFace = it->getFace();134     this->sendInterest(pitEntry, outFace);135     NFD_LOG_DEBUG(interest << " from=" << inFace.getId()136                            << " newPitEntry-to=" << outFace->getId());137     return;138   }139 140   if (suppression == RetxSuppression::SUPPRESS) {141     NFD_LOG_DEBUG(interest << " from=" << inFace.getId()142                            << " suppressed");143     return;144   }145 146   // find an unused upstream with lowest cost except downstream147   it = std::find_if(nexthops.begin(), nexthops.end(),148                     bind(&predicate_NextHop_eligible, pitEntry, _1, inFace.getId(),149                          true, time::steady_clock::now()));150   if (it != nexthops.end()) {151     shared_ptr<Face> outFace = it->getFace();152     this->sendInterest(pitEntry, outFace);153     NFD_LOG_DEBUG(interest << " from=" << inFace.getId()154                            << " retransmit-unused-to=" << outFace->getId());155     return;156   }157 158   // find an eligible upstream that is used earliest159   it = findEligibleNextHopWithEarliestOutRecord(pitEntry, nexthops, inFace.getId());160   if (it == nexthops.end()) {161     NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " retransmitNoNextHop");162   }163   else {164     shared_ptr<Face> outFace = it->getFace();165     this->sendInterest(pitEntry, outFace);166     NFD_LOG_DEBUG(interest << " from=" << inFace.getId()167                            << " retransmit-retry-to=" << outFace->getId());168   }169 }170 175 inline lp::NackReason176 compareLessSevere(lp::NackReason x, lp::NackReason y)177 {178   if (x == lp::NackReason::NONE) {179     return y;180   }181   if (y == lp::NackReason::NONE) {182     return x;183   }184   return static_cast<lp::NackReason>(std::min(static_cast<int>(x), static_cast<int>(y)));185 }186 187 void188 BestRouteStrategy2::afterReceiveNack(const Face& inFace, const lp::Nack& nack,189                                      shared_ptr<fib::Entry> fibEntry,190                                      shared_ptr<pit::Entry> pitEntry)191 {192   int nOutRecordsNotNacked = 0;193   Face* lastFaceNotNacked = nullptr;194   lp::NackReason leastSevereReason = lp::NackReason::NONE;195   for (const pit::OutRecord& outR : pitEntry->getOutRecords()) {196     const lp::NackHeader* inNack = outR.getIncomingNack();197     if (inNack == nullptr) {198       ++nOutRecordsNotNacked;199       lastFaceNotNacked = outR.getFace().get();200       continue;201     }202 203     leastSevereReason = compareLessSevere(leastSevereReason, inNack->getReason());204   }205 206   lp::NackHeader outNack;207   outNack.setReason(leastSevereReason);208 209   if (nOutRecordsNotNacked == 1) {210     BOOST_ASSERT(lastFaceNotNacked != nullptr);211     pit::InRecordCollection::const_iterator inR = pitEntry->getInRecord(*lastFaceNotNacked);212     if (inR != pitEntry->getInRecords().end()) {213       // one out-record not Nacked, which is also a downstream214       NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<215                     " nack=" << nack.getReason() <<216                     " nack-to(bidirectional)=" << lastFaceNotNacked->getId() <<217                     " out-nack=" << outNack.getReason());218       this->sendNack(pitEntry, *lastFaceNotNacked, outNack);219       return;220     }221   }222 223   if (nOutRecordsNotNacked > 0) {224     NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<225                   " nack=" << nack.getReason() <<226                   " waiting=" << nOutRecordsNotNacked);227     // continue waiting228     return;229   }230 231 232   NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<233                 " nack=" << nack.getReason() <<234                 " nack-to=all out-nack=" << outNack.getReason());235   this->sendNacks(pitEntry, outNack);236 }237 238 } // namespace fw239 } // namespace nfd

exponential backoff algorithm相关推荐

  1. flume之退避算法backoff algorithm

    flume之退避算法backoff algorithm 什么是退避算法: In a single channel contention based medium access control (MAC ...

  2. 通过Akka学习指数退避(Exponential Backoff)

    原文连接:https://mincong.io/cn/exponential-backoff-in-akka/ 前言 在软件开发中,我们免不了要跟各种错误异常打交道.比如说,当一个服务在调用另一个服务 ...

  3. Binary Exponential Backoff

    一.CSMA/CD过程 CSMA/CD就像在没有主持人的座谈会中,所有的参加者都通过一个共同的媒介(空气)来相互 交谈.每个参加者在讲话前,都礼貌地等待别人把话讲完.如果两个客人同时开始讲话,那么他们 ...

  4. [Android Traffic] 调整定时更新的频率(C2DM与退避算法)

    转载自: http://blog.csdn.net/kesenhoo/article/details/7395253 Minimizing the Effect of Regular Updates[ ...

  5. 小程序 坚屏_如何构建坚如磐石的应用程序

    小程序 坚屏 不同的应用程序设计选项概述 (An overview of different app design options) When we design software, we const ...

  6. 避免大规模故障的微服务架构设计之道

    作者:Péter Márton  译者:Jackyrong 本文首先介绍微服务架构存在的风险,然后针对如何避免微服务架构的故障,提出了多种有效的微服务架构中的方法和技术,其中例如服务降级.变更管理.健 ...

  7. 一文带你复习计网中的重点知识(一万五千字长文)

    建议参考西安交通大学计网考后总结及复习资料汇总进行复习 本文是第一次复习时的整理资料,包括缩写名词解释,重要概念,重要算法,各种表以及报文协议 如需pdf,请在下方留言 文章目录 名词解释 填空概念 ...

  8. CSMACA 与 CSMA/CD 区别

    CSMA/CA 载波检测多路存取/碰撞避免(Carrier Sense Multiple Access/Collision Avoidance, CSMA/CA)是802.11无线局域网标准中采用的媒 ...

  9. AWS DynamoDB的简介与使用

    DynamoDB的简介 Amazon Dynamodb是一种快速灵活的NoSQL数据库服务,适用于所有需要一致的单位毫秒延迟的应用程序.它是一个完全管理的云数据库,支持文档和关键价值存储模型.其灵活的 ...

最新文章

  1. 找啊找啊找木偶,图灵奖得主G. Hinton第一篇论文曝光!
  2. 需求分析--12章 过程建模
  3. 三层交换机如何封装trunk_锐捷交换机常用配置命令汇总
  4. Android Activity动画属性简介
  5. Winform开发之ADO.NET对象Connection、Command、DataReader、DataAdapter、DataSet和DataTable简介...
  6. LeetCode 2087. 网格图中机器人回家的最小代价(脑筋急转弯)
  7. LeetCode 1094. 拼车
  8. 4.4.3 日期与时间计算
  9. JAVASCRIPT视频教程推荐==李炎恢JavaScript教程 第一季
  10. 快速打造 Android 自定义表情库
  11. 【Android自动化测试】Robot Framework+adb框架(四)——L2层关键字
  12. html怎么安装系统,一键重装系统_MBR分区一键安装系统教程-爱纯净
  13. 站内信功能 java_站内信功能
  14. Android10.0CarAudioZone(一)
  15. 复变函数(1)-复数及其几何属性
  16. jeecg官网(jeecg官网 ios开发)
  17. 【计算机网络学习笔记】分组交换的原理
  18. 学习笔记:MAC协议 5GNR
  19. 【七里香】雨下整夜 我的爱溢出就像雨水
  20. 2018金华高一计算机考试题目,2018年9月金华十校信息技术考试试题(含解析).docx...

热门文章

  1. 网络写作一年稿酬最高可达150万元
  2. UVa OJ 126 - The Errant Physicist (粗心的物理学家)
  3. 手机剪辑视频指南:去水印、加字幕、做转场,统统一键就搞定
  4. springBoot启动类报错
  5. 判断抽样检验产品是否合格的步骤
  6. Could not extract response: no suitable HttpMessageConverter found for response type [class com.exam
  7. Android真机连接局域网PC服务器的方法
  8. gamma correct blurring
  9. 云渲染和渲染农场有什么区别?看完你就明白了
  10. idea translation翻译插件报-TKK错误