blob: 5faad790616418aaa545efe5d6febd87f48f9a60 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <perfdhcp/rate_control.h>
#include <exceptions/exceptions.h>
namespace isc {
namespace perfdhcp {
using namespace boost::posix_time;
RateControl::RateControl()
: rate_(0), total_pkts_sent_count_(0) {
}
RateControl::RateControl(const unsigned int rate)
: rate_(rate), total_pkts_sent_count_(0) {
}
uint64_t
RateControl::getOutboundMessageCount(bool const waiting_to_exit /* = false */) {
if (total_pkts_sent_count_ == 0) {
start_time_ = currentTime();
total_pkts_sent_count_ = 1;
return 1;
}
// If rate is not limited, then each time send 1 packet.
if (getRate() == 0) {
return 1;
}
// If we've entered exit wait time's zone, stop sending.
if (waiting_to_exit) {
return 0;
}
// Estimate number of packets to sent. If we are behind of time we will
// try to catch up to upkeep request rate by sending more packets in one cycle.
auto now = currentTime();
time_period period(start_time_, now);
time_duration duration = period.length();
uint64_t should_sent_pkts_count = static_cast<double>(getRate()) / static_cast<double>(time_duration::ticks_per_second()) * duration.ticks();
if (should_sent_pkts_count <= total_pkts_sent_count_) {
return 0;
}
auto pending_pkts_count = should_sent_pkts_count - total_pkts_sent_count_;
// Reduce bursts to have more uniform traffic.
if (pending_pkts_count > 3) {
pending_pkts_count = 3;
}
total_pkts_sent_count_ += pending_pkts_count;
return pending_pkts_count;
}
boost::posix_time::ptime
RateControl::currentTime() {
return (microsec_clock::universal_time());
}
void
RateControl::setRate(const int rate) {
if (rate < 0) {
isc_throw(isc::BadValue, "invalid value of rate " << rate
<< ", expected non-negative value");
}
rate_ = rate;
}
} // namespace perfdhcp
} // namespace isc
|