Browse Source

Move responsibility for voting into a separate periodic callback.

Closes ticket25937.
Nick Mathewson 6 years ago
parent
commit
6868398b69
2 changed files with 41 additions and 4 deletions
  1. 9 0
      changes/ticket25937
  2. 32 4
      src/or/main.c

+ 9 - 0
changes/ticket25937

@@ -0,0 +1,9 @@
+  o Minor features (mainloop):
+    - Move responsibility for
+      consensus voting
+      from a once-per-second callback to a callback that is only scheduled as
+      needed.  Once enough items are removed from our once-per-second
+      callback, we can eliminate it entirely to conserve CPU when idle.
+      Closes ticket
+      25937.
+

+ 32 - 4
src/or/main.c

@@ -1341,6 +1341,7 @@ CALLBACK(check_for_reachability_bw);
 CALLBACK(check_onion_keys_expiry_time);
 CALLBACK(clean_caches);
 CALLBACK(clean_consdiffmgr);
+CALLBACK(dirvote);
 CALLBACK(downrate_stability);
 CALLBACK(expire_old_ciruits_serverside);
 CALLBACK(fetch_networkstatus);
@@ -1402,6 +1403,7 @@ STATIC periodic_event_item_t periodic_events[] = {
 
   /* Directory authority only. */
   CALLBACK(check_authority_cert, PERIODIC_EVENT_ROLE_DIRAUTH, 0),
+  CALLBACK(dirvote, PERIODIC_EVENT_ROLE_DIRAUTH, PERIODIC_EVENT_FLAG_NEED_NET),
 
   /* Relay only. */
   CALLBACK(check_canonical_channels, PERIODIC_EVENT_ROLE_RELAY,
@@ -1718,10 +1720,6 @@ run_scheduled_events(time_t now)
     accounting_run_housekeeping(now);
   }
 
-  if (authdir_mode_v3(options)) {
-    dirvote_act(options, now);
-  }
-
   /* 3a. Every second, we examine pending circuits and prune the
    *    ones which have been pending for more than a few seconds.
    *    We do this before step 4, so it can try building more if
@@ -1973,6 +1971,36 @@ check_authority_cert_callback(time_t now, const or_options_t *options)
   return CHECK_V3_CERTIFICATE_INTERVAL;
 }
 
+/**
+ * Scheduled callback: Run directory-authority voting functionality.
+ *
+ * The schedule is a bit complicated here, so dirvote_act() manages the
+ * schedule itself.
+ **/
+static int
+dirvote_callback(time_t now, const or_options_t *options)
+{
+  if (!authdir_mode_v3(options)) {
+    tor_assert_nonfatal_unreached();
+    return 3600;
+  }
+
+  time_t next = dirvote_act(options, now);
+  if (BUG(next == TIME_MAX)) {
+    /* This shouldn't be returned unless we called dirvote_act() without
+     * being an authority.  If it happens, maybe our configuration will
+     * fix itself in an hour or so? */
+    return 3600;
+  }
+  if (BUG(next <= now)) {
+    /* This case shouldn't be possible, since "next" is computed by
+     * dirvote_act() based on the value of "now" we give it. */
+    return 1;
+  } else {
+    return next - now;
+  }
+}
+
 /**
  * Periodic callback: If our consensus is too old, recalculate whether
  * we can actually use it.