From e4b1478488f163422022c48588cf4950f224ba04 Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Wed, 10 Jun 2015 16:01:19 +0200 Subject: [PATCH] added delay to pingers with random interval; delay all first pings So far the mostly had no delay at all, now the delay is random in [0, interval]. For all pingers set a little delay before first ping --- src/main.cpp | 42 +++++++++++++++++++++++++++++++++++------- 1 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5e96a72..4ea7634 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,6 +29,9 @@ on this file might be covered by the GNU General Public License. #include #include #include +#include +#include +#include #include #include @@ -207,8 +210,8 @@ void set_log_output( * of hosts with same ping intervals, to distribute them as evenly as * possible, right from the start (might diverge over time, anyway). * - * Will not do much good for pingers with many different intervals, but - * then is not required anyway and does no(t much) harm. + * If interval is chosen at random, will have many pingers with different + * intervals; to those will assign a random delay in [0, interval]. * * Called by init_pingers with * @param hosts list of hosts as obtained from configuration @@ -228,12 +231,35 @@ DelayMap calc_pinger_delays(const HostList &hosts) delay_shifts[curr_interval] += 1.0f; } + // create random number generator + typedef boost::rand48 rand_gen_type; + typedef boost::uniform_real rand_dist_type; + typedef boost::variate_generator< rand_gen_type&, + rand_dist_type > rand_var_type; + rand_gen_type random_number_generator( + boost::numeric_cast(time(0)) ); + // second step: divide intervals by counts, round to int // --> for 18 pingers with a 30s interval, get 30s/18 = 1.66667 + // for random intervals, use random delays within intervals BOOST_FOREACH( IntervalCountPair interval_and_count, delay_shifts ) - delay_shifts[interval_and_count.first] = - boost::numeric_cast(interval_and_count.first) / - interval_and_count.second; + { + if ( interval_and_count.second == 1 ) + { // there is exactly 1 pinger with exactly that interval + // --> assign a random delay within interval + rand_dist_type random_distribution(0, interval_and_count.first); + rand_var_type random_variate(random_number_generator, + random_distribution); + delay_shifts[interval_and_count.first] = random_variate(); + } + else + { // there are several pingers with same interval + // --> distribute evenly + delay_shifts[interval_and_count.first] = + boost::numeric_cast(interval_and_count.first) / + interval_and_count.second; + } + } return delay_shifts; } @@ -255,7 +281,7 @@ bool init_pingers( // calculate delays between pingers of same interval DelayMap delay_shifts = calc_pinger_delays(configuration->get_hosts()); - // setup memory for assigned delays + // setup memory for assigned delays; init with delay > 0 DelayMap delays; BOOST_FOREACH( IntervalCountPair interval_and_delay, delay_shifts ) delays[interval_and_delay.first] = 0.0f; @@ -285,8 +311,10 @@ bool init_pingers( int ping_interval_in_sec = host->get_interval_in_sec(); // get delay for this scheduler and update assigned delays - int current_delay = boost::math::iround(delays[ping_interval_in_sec]); delays[ping_interval_in_sec] += delay_shifts[ping_interval_in_sec]; + int current_delay = boost::math::iround(delays[ping_interval_in_sec]); + GlobalLogger.notice() << "TEST: assigning delay of " << current_delay + << "s to pinger with interval " << ping_interval_in_sec << "s"; PingSchedulerItem scheduler( new PingScheduler( -- 1.7.1