rate_control.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef RATE_CONTROL_H
  15. #define RATE_CONTROL_H
  16. #include <boost/date_time/posix_time/posix_time.hpp>
  17. namespace isc {
  18. namespace perfdhcp {
  19. /// \brief A message sending rate control class for perfdhcp.
  20. ///
  21. /// This class provides the means to control the rate at which messages
  22. /// of the specific type are sent by perfdhcp. Each message type,
  23. /// for which the desired rate can be specified, has a corresponding
  24. /// \c RateControl object. So, the perfdhcp is using up to three objects
  25. /// of this type at the same time, to control the rate of the following
  26. /// messages being sent:
  27. /// - Discover(DHCPv4) or Solicit (DHCPv6)
  28. /// - Renew (DHCPv6) or Request (DHCPv4) to renew leases.
  29. /// - Release
  30. ///
  31. /// The purpose of the RateControl class is to track the due time for
  32. /// sending next message (or bunch of messages) to keep outbound rate
  33. /// of particular messages at the desired level. The due time is calculated
  34. /// using the desired rate value and the timestamp when the last message of
  35. /// the particular type has been sent. That puts the responsibility on the
  36. /// \c TestControl class to invoke the \c RateControl::updateSendDue, every
  37. /// time the message is sent.
  38. ///
  39. /// The \c RateControl object returns the number of messages to be sent at
  40. /// the time. The number returned is 0, if perfdhcp shouldn't send any messages
  41. /// yet, or 1 (sometimes more) if the send due time has been reached.
  42. class RateControl {
  43. public:
  44. /// \brief Default constructor.
  45. RateControl();
  46. /// \brief Constructor which sets desired rate and aggressivity.
  47. ///
  48. /// \param rate A desired rate.
  49. /// \param aggressivity A desired aggressivity.
  50. RateControl(const int rate, const int aggressivity);
  51. /// \brief Returns the value of aggressivity.
  52. int getAggressivity() const {
  53. return (aggressivity_);
  54. }
  55. /// \brief Returns current due time to send next message.
  56. boost::posix_time::ptime getDue() const {
  57. return (send_due_);
  58. }
  59. /// \brief Returns number of messages to be sent "now".
  60. ///
  61. /// This function calculates how many messages of the given type should
  62. /// be sent immediately when the call to the function returns, to catch
  63. /// up with the desired message rate.
  64. ///
  65. /// The value returned depends on the due time calculated with the
  66. /// \c RateControl::updateSendDue function and the current time. If
  67. /// the due time has been hit, the non-zero number of messages is returned.
  68. /// If the due time hasn't been hit, the number returned is 0.
  69. ///
  70. /// If the rate is non-zero, the number of messages to be sent is calculated
  71. /// as follows:
  72. /// \code
  73. /// num = duration * rate
  74. /// \endcode
  75. /// where <b>duration</b> is a time period between the due time to send
  76. /// next set of messages and current time. The duration is expressed in
  77. /// seconds with the fractional part having 6 or 9 digits (depending on
  78. /// the timer resolution). If the calculated value is equal to 0, it is
  79. /// rounded to 1, so as at least one message is sent.
  80. ///
  81. /// The value of aggressivity limits the maximal number of messages to
  82. /// be sent one after another. If the number of messages calculated with
  83. /// the equation above exceeds the aggressivity, this function will return
  84. /// the value equal to aggressivity.
  85. ///
  86. /// If the rate is not specified (equal to 0), the value calculated by
  87. /// this function is equal to aggressivity.
  88. ///
  89. /// \return A number of messages to be sent immediately.
  90. uint64_t getOutboundMessageCount();
  91. /// \brief Returns the rate.
  92. int getRate() const {
  93. return (rate_);
  94. }
  95. /// \brief Returns the value of the late send flag.
  96. ///
  97. /// The flag returned by this function indicates whether the new due time
  98. /// calculated by the \c RateControl::updateSendDue is in the past.
  99. /// This value is used by the \c TestControl object to increment the counter
  100. /// of the late sent messages in the \c StatsMgr.
  101. bool isLateSent() const {
  102. return (late_sent_);
  103. }
  104. /// \brief Sets the value of aggressivity.
  105. ///
  106. /// \param aggressivity A new value of aggressivity. This value must be
  107. /// a positive integer.
  108. /// \throw isc::BadValue if new value is not a positive integer.
  109. void setAggressivity(const int aggressivity);
  110. /// \brief Sets the new rate.
  111. ///
  112. /// \param rate A new value of rate. This value must not be negative.
  113. /// \throw isc::BadValue if new rate is negative.
  114. void setRate(const int rate);
  115. /// \brief Sets the value of the due time.
  116. ///
  117. /// This function is intended for unit testing. It manipulates the value of
  118. /// the due time. The parameter passed to this function specifies the
  119. /// (positive or negative) number of seconds relative to current time.
  120. ///
  121. /// \param offset A number of seconds relative to current time which
  122. /// constitutes the new due time.
  123. void setRelativeDue(const int offset);
  124. /// \brief Sets the timestamp of the last sent message to current time.
  125. void updateSendTime();
  126. protected:
  127. /// \brief Convenience function returning current time.
  128. ///
  129. /// \return current time.
  130. static boost::posix_time::ptime currentTime();
  131. /// \brief Calculates the send due.
  132. ///
  133. /// This function calculates the send due timestamp using the current time
  134. /// and desired rate. The due timestamp is calculated as a sum of the
  135. /// timestamp when the last message was sent and the reciprocal of the rate
  136. /// in micro or nanoseconds (depending on the timer resolution). If the rate
  137. /// is not specified, the duration between two consecutive sends is one
  138. /// timer tick.
  139. void updateSendDue();
  140. /// \brief Holds a timestamp when the next message should be sent.
  141. boost::posix_time::ptime send_due_;
  142. /// \brief Holds a timestamp when the last message was sent.
  143. boost::posix_time::ptime last_sent_;
  144. /// \brief Holds an aggressivity value.
  145. int aggressivity_;
  146. /// \brief Holds a desired rate value.
  147. int rate_;
  148. /// \brief A flag which indicates that the calculated due time is in the
  149. /// past.
  150. bool late_sent_;
  151. };
  152. }
  153. }
  154. #endif