Kea 1.5.0
rate_control.cc
Go to the documentation of this file.
1// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
10#include "rate_control.h"
11
12namespace isc {
13namespace perfdhcp {
14
15using namespace boost::posix_time;
16
18 : send_due_(currentTime()), last_sent_(currentTime()),
19 aggressivity_(1), rate_(0), late_sent_(false) {
20}
21
22RateControl::RateControl(const int rate, const int aggressivity)
23 : send_due_(currentTime()), last_sent_(currentTime()),
24 aggressivity_(aggressivity), rate_(rate), late_sent_(false) {
25 if (aggressivity_ < 1) {
26 isc_throw(isc::BadValue, "invalid value of aggressivity "
27 << aggressivity << ", expected value is greater than 0");
28 }
29 if (rate_ < 0) {
30 isc_throw(isc::BadValue, "invalid value of rate " << rate
31 << ", expected non-negative value");
32 }
33}
34
35uint64_t
37
38 // We need calculate the due time for sending next set of messages.
40
41 // Get current time. If we are behind due time, we have to calculate
42 // how many messages to send to catch up with the rate.
43 ptime now = currentTime();
44 if (now >= send_due_) {
45 // Reset number of exchanges.
46 uint64_t due_exchanges = 0;
47 // If rate is specified from the command line we have to
48 // synchronize with it.
49 if (getRate() != 0) {
50 time_period period(send_due_, now);
51 time_duration duration = period.length();
52 // due_factor indicates the number of seconds that
53 // sending next chunk of packets will take.
54 double due_factor =
55 static_cast<double>(duration.fractional_seconds()) /
56 static_cast<double>(time_duration::ticks_per_second());
57 due_factor += static_cast<double>(duration.total_seconds());
58 // Multiplying due_factor by expected rate gives the number
59 // of exchanges to be initiated.
60 due_exchanges = static_cast<uint64_t>(due_factor * getRate());
61 // We want to make sure that at least one packet goes out.
62 if (due_exchanges == 0) {
63 due_exchanges = 1;
64 }
65 // We should not exceed aggressivity as it could have been
66 // restricted from command line.
67 if (due_exchanges > getAggressivity()) {
68 due_exchanges = getAggressivity();
69 }
70 } else {
71 // Rate is not specified so we rely on aggressivity
72 // which is the number of packets to be sent in
73 // one chunk.
74 due_exchanges = getAggressivity();
75 }
76 return (due_exchanges);
77 }
78 return (0);
79}
80
81boost::posix_time::ptime
83 return (microsec_clock::universal_time());
84}
85
86void
88 // There is no sense to update due time if the current due time is in the
89 // future. The due time is calculated as a duration between the moment
90 // when the last message of the given type was sent and the time when
91 // next one is supposed to be sent based on a given rate. The former value
92 // will not change until we send the next message, which we don't do
93 // until we reach the due time.
94 if (send_due_ > currentTime()) {
95 return;
96 }
97 // This is initialized in the class constructor, so if it is not initialized
98 // it is a programmatic error.
99 if (last_sent_.is_not_a_date_time()) {
100 isc_throw(isc::Unexpected, "timestamp of the last sent packet not"
101 " initialized");
102 }
103 // If rate was not specified we will wait just one clock tick to
104 // send next packet. This simulates best effort conditions.
105 long duration = 1;
106 if (getRate() != 0) {
107 // We use number of ticks instead of nanoseconds because
108 // nanosecond resolution may not be available on some
109 // machines. Number of ticks guarantees the highest possible
110 // timer resolution.
111 duration = time_duration::ticks_per_second() / getRate();
112 }
113 // Calculate due time to initiate next chunk of exchanges.
114 send_due_ = last_sent_ + time_duration(0, 0, 0, duration);
115 if (send_due_ > currentTime()) {
116 late_sent_ = true;
117 } else {
118 late_sent_ = false;
119 }
120}
121
122void
123RateControl::setAggressivity(const int aggressivity) {
124 if (aggressivity < 1) {
125 isc_throw(isc::BadValue, "invalid value of aggressivity "
126 << aggressivity << ", expected value is greater than 0");
127 }
128 aggressivity_ = aggressivity;
129}
130
131void
132RateControl::setRate(const int rate) {
133 if (rate < 0) {
134 isc_throw(isc::BadValue, "invalid value of rate " << rate
135 << ", expected non-negative value");
136 }
137 rate_ = rate;
138}
139
140void
142 send_due_ = offset > 0 ?
143 currentTime() + seconds(abs(offset)) :
144 currentTime() - seconds(abs(offset));
145}
146
147void
150}
151
152} // namespace perfdhcp
153} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when an unexpected error condition occurs.
int getRate() const
Returns the rate.
Definition: rate_control.h:94
static boost::posix_time::ptime currentTime()
Convenience function returning current time.
Definition: rate_control.cc:82
int aggressivity_
Holds an aggressivity value.
Definition: rate_control.h:158
int getAggressivity() const
Returns the value of aggressivity.
Definition: rate_control.h:51
RateControl()
Default constructor.
Definition: rate_control.cc:17
bool late_sent_
A flag which indicates that the calculated due time is in the past.
Definition: rate_control.h:165
boost::posix_time::ptime last_sent_
Holds a timestamp when the last message was sent.
Definition: rate_control.h:155
void setAggressivity(const int aggressivity)
Sets the value of aggressivity.
void updateSendTime()
Sets the timestamp of the last sent message to current time.
void updateSendDue()
Calculates the send due.
Definition: rate_control.cc:87
boost::posix_time::ptime send_due_
Holds a timestamp when the next message should be sent.
Definition: rate_control.h:152
void setRate(const int rate)
Sets the new rate.
void setRelativeDue(const int offset)
Sets the value of the due time.
int rate_
Holds a desired rate value.
Definition: rate_control.h:161
uint64_t getOutboundMessageCount()
Returns number of messages to be sent "now".
Definition: rate_control.cc:36
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
string currentTime()
Create Time.
Defines the logger used by the top-level component of kea-dhcp-ddns.