added delay to pingers with random interval; delay all first pings
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 10 Jun 2015 14:01:19 +0000 (16:01 +0200)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 10 Jun 2015 14:01:19 +0000 (16:01 +0200)
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

index 5e96a72..4ea7634 100644 (file)
@@ -29,6 +29,9 @@ on this file might be covered by the GNU General Public License.
 #include <boost/math/special_functions/round.hpp>
 #include <boost/numeric/conversion/cast.hpp>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/variate_generator.hpp>
 
 #include <daemonfunc.hpp>
 #include <logfunc.hpp>
@@ -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<float> 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<unsigned int>(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<float>(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<float>(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(