Changeset 3347d53135a735b1a63caebd183d91dae3088dd3

Show
Ignore:
Timestamp:
12/04/11 02:42:26 (2 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1322966546 -0500
git-parent:

[dcfcfffba3a8619a404899e11101c53b8a2d48c6]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1322966546 -0500
Message:

Do away with the initial stutter and randomness as it was and equally
space checks out in 20ms buckets with jitter within those buckets.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • docs/operation/cli/cli.xml

    r23dea7e r3347d53  
    377377        noit(conf:/checks)# ls 
    378378        == Section Settings == 
    379         @max_initial_stutter: 30000 
    380379        @filterset: default 
    381380        @transient_min_period: 1000 
  • src/noit.conf.in

    r68aa702 r3347d53  
    109109    </acl> 
    110110  </rest> 
    111   <checks max_initial_stutter="30000" filterset="default" 
     111  <checks filterset="default" 
    112112          resolve_rtype="prefer-ipv4" 
    113113          transient_min_period="1000" transient_period_granularity="500"> 
  • src/noit_check.c

    r0d859ed r3347d53  
    5555#include "eventer/eventer.h" 
    5656 
    57 /* 60 seconds of possible stutter */ 
    58 #define MAX_INITIAL_STUTTER 6000
     57/* 10 ms slots over 60 second for distribution */ 
     58#define SCHEDULE_GRANULARITY 2
    5959 
    6060static u_int64_t check_completion_count = 0; 
     
    6363static noit_skiplist polls_by_name = { 0 }; 
    6464static u_int32_t __config_load_generation = 0; 
     65static unsigned short check_slots_count[60000 / SCHEDULE_GRANULARITY] = { 0 }, 
     66                      check_slots_seconds_count[60] = { 0 }; 
    6567 
    6668u_int64_t noit_check_completion_count() { 
     
    7173                                       struct timeval *); 
    7274 
     75static int 
     76check_slots_find_smallest() { 
     77  int i, j, jbase = 0, mini = 0, minj = 0; 
     78  unsigned short min_running_i = 0xffff, min_running_j = 0xffff; 
     79  for(i=0;i<60;i++) { 
     80    if(check_slots_seconds_count[i] < min_running_i) { 
     81      min_running_i = check_slots_seconds_count[i]; 
     82      mini = i; 
     83    } 
     84  } 
     85  jbase = mini * (1000/SCHEDULE_GRANULARITY); 
     86  for(j=jbase;j<jbase+(1000/SCHEDULE_GRANULARITY);j++) { 
     87    if(check_slots_count[j] < min_running_j) { 
     88      min_running_j = check_slots_count[j]; 
     89      minj = j; 
     90    } 
     91  } 
     92  return (minj * SCHEDULE_GRANULARITY) + drand48() * SCHEDULE_GRANULARITY; 
     93} 
     94static void 
     95check_slots_adjust_tv(struct timeval *tv, short adj) { 
     96  int offset_ms, idx; 
     97  offset_ms = (tv->tv_sec % 60) * 1000 + (tv->tv_usec / 1000); 
     98  idx = offset_ms / SCHEDULE_GRANULARITY; 
     99  check_slots_count[idx] += adj; 
     100  check_slots_seconds_count[offset_ms / 1000] += adj; 
     101} 
     102void check_slots_inc_tv(struct timeval *tv) { 
     103  check_slots_adjust_tv(tv, 1); 
     104} 
     105void check_slots_dec_tv(struct timeval *tv) { 
     106  check_slots_adjust_tv(tv, -1); 
     107} 
    73108const char * 
    74109noit_check_available_string(int16_t available) { 
     
    117152  return flags; 
    118153} 
    119 int 
    120 noit_check_max_initial_stutter() { 
    121   int stutter; 
    122   if(!noit_conf_get_int(NULL, "/noit/checks/@max_initial_stutter", &stutter)) 
    123     stutter = MAX_INITIAL_STUTTER; 
    124   return stutter; 
    125 } 
    126154void 
    127155noit_check_fake_last_check(noit_check_t *check, 
    128156                           struct timeval *lc, struct timeval *_now) { 
    129157  struct timeval now, period; 
    130   static int start_offset_ms = -1; 
    131   int offset = 0, max; 
    132  
    133   if(start_offset_ms == -1) 
    134     start_offset_ms = drand48() * noit_check_max_initial_stutter(); 
    135   if(!(check->flags & NP_TRANSIENT) && check->period) { 
    136     max = noit_check_max_initial_stutter(); 
    137     offset = start_offset_ms + drand48() * 1000; 
    138     offset = offset % MIN(max, check->period); 
    139     start_offset_ms += 1000; 
    140   } 
    141   period.tv_sec = (check->period - offset) / 1000; 
    142   period.tv_usec = ((check->period - offset) % 1000) * 1000; 
     158  int balance_ms; 
     159 
    143160  if(!_now) { 
    144161    gettimeofday(&now, NULL); 
    145162    _now = &now; 
    146163  } 
     164  period.tv_sec = check->period / 1000; 
     165  period.tv_usec = (check->period % 1000) * 1000; 
    147166  sub_timeval(*_now, period, lc); 
     167 
     168  if(!(check->flags & NP_TRANSIENT) && check->period) { 
     169    balance_ms = check_slots_find_smallest(); 
     170    lc->tv_sec = (lc->tv_sec / 60) * 60 + balance_ms / 1000; 
     171    lc->tv_usec = (balance_ms % 1000) * 1000; 
     172    if(compare_timeval(*_now, *lc) < 0) 
     173      sub_timeval(*lc, period, lc); 
     174    else { 
     175      struct timeval test; 
     176      while(1) { 
     177        add_timeval(*lc, period, &test); 
     178        if(compare_timeval(*_now, test) < 0) break; 
     179        memcpy(lc, &test, sizeof(test)); 
     180      } 
     181    } 
     182  } 
     183  /* now, we're going to do an even distribution using the slots */ 
     184  if(!(check->flags & NP_TRANSIENT)) check_slots_inc_tv(lc); 
    148185} 
    149186void 
  • src/noit_check.h

    r899f2d2 r3347d53  
    178178  noit_check_fake_last_check(noit_check_t *check, 
    179179                             struct timeval *lc, struct timeval *_now); 
    180 API_EXPORT(int) noit_check_max_initial_stutter(); 
    181180 
    182181API_EXPORT(int) 
     
    305304                               int argc, char **argv, int idx); 
    306305 
     306API_EXPORT(void) check_slots_inc_tv(struct timeval *tv); 
     307API_EXPORT(void) check_slots_dec_tv(struct timeval *tv); 
     308 
    307309#endif 
  • src/noit_check_tools.c

    r899f2d2 r3347d53  
    8383  assert(check->fire_event == NULL); 
    8484  if(check->period == 0) return 0; 
    85   if(NOIT_CHECK_DISABLED(check) || NOIT_CHECK_KILLED(check)) return 0; 
     85  if(NOIT_CHECK_DISABLED(check) || NOIT_CHECK_KILLED(check)) { 
     86    if(!(check->flags & NP_TRANSIENT)) check_slots_dec_tv(last_check); 
     87    return 0; 
     88  } 
    8689 
    8790  /* If we have an event, we know when we intended it to fire.  This means 
  • src/noit_defines.h

    r4ace564 r3347d53  
    6565} 
    6666 
     67static inline double sub_timeval_d(struct timeval a, struct timeval b) 
     68{ 
     69  struct timeval d; 
     70  sub_timeval(a,b,&d); 
     71  return (double)d.tv_sec + (double)d.tv_usec / 1000000.0; 
     72} 
     73 
    6774static inline void add_timeval(struct timeval a, struct timeval b, 
    6875                               struct timeval *out)