[tor-commits] [torflow/master] Implement per-class setpoints.
mikeperry at torproject.org
mikeperry at torproject.org
Fri Dec 2 04:56:42 UTC 2011
commit 4f4bc10fba85adc877481e3fb4445847a208da12
Author: Mike Perry <mikeperry-git at fscked.org>
Date: Thu Dec 1 20:09:25 2011 -0800
Implement per-class setpoints.
Governed by consensus param (off by default).
---
NetworkScanners/BwAuthority/README.spec.txt | 5 ++
NetworkScanners/BwAuthority/aggregate.py | 65 ++++++++++++++++++++++-----
2 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/NetworkScanners/BwAuthority/README.spec.txt b/NetworkScanners/BwAuthority/README.spec.txt
index 81468b5..acce106 100644
--- a/NetworkScanners/BwAuthority/README.spec.txt
+++ b/NetworkScanners/BwAuthority/README.spec.txt
@@ -528,6 +528,11 @@
accumulated in pid_error_sum as opposed to the consensus value
itself.
+ "bwauthbyclass=1"
+ If present, computes F_avg (see Section 3.1) for each class
+ of Guard, Middle, Exit, and Guard+Exit nodes, and uses these
+ flag-specific averages to compute pid_error.
+
"bwauthkp=N"
Sets K_p to N/10000.0. If absent, K_p=1.0.
diff --git a/NetworkScanners/BwAuthority/aggregate.py b/NetworkScanners/BwAuthority/aggregate.py
index 6283f3f..120de07 100755
--- a/NetworkScanners/BwAuthority/aggregate.py
+++ b/NetworkScanners/BwAuthority/aggregate.py
@@ -92,6 +92,7 @@ class Node:
self.new_bw = None
self.change = None
self.use_bw = -1
+ self.flags = ""
# measurement vars from bwauth lines
self.measured_at = 0
@@ -132,6 +133,16 @@ class Node:
+ kd*self.use_bw*self.d_error_dt()
return self.pid_bw
+ def node_class(self):
+ if "Guard" in self.flags and "Exit" in self.flags:
+ return "Guard+Exit"
+ elif "Guard" in self.flags:
+ return "Guard"
+ elif "Exit" in self.flags:
+ return "Exit"
+ else:
+ return "Middle"
+
# Time-weighted sum of error per unit of time (measurement sample)
def integral_error(self):
if self.prev_error == 0:
@@ -222,6 +233,7 @@ class ConsensusJunk:
def __init__(self, c):
cs_bytes = c.sendAndRecv("GETINFO dir/status-vote/current/consensus\r\n")[0][2]
self.bwauth_pid_control = True
+ self.group_by_class = False
self.use_circ_fails = False
self.use_best_ratio = True
self.use_desc_bw = True
@@ -246,6 +258,9 @@ class ConsensusJunk:
elif p == "bwauthbestratio=0":
self.use_best_ratio = False
plog("INFO", "Choosing larger of sbw vs fbw")
+ elif p == "bwauthbyclass=1":
+ self.group_by_class = True
+ plog("INFO", "Grouping nodes by flag-class")
elif p.startswith("bwauthkp="):
self.K_p = int(p.split("=")[1])/10000.0
plog("INFO", "Got K_p=%f from consensus." % self.K_p)
@@ -439,23 +454,45 @@ def main(argv):
for n in nodes.itervalues():
n.circ_fail_rate = 0.0
+ for idhex in nodes.iterkeys():
+ if idhex in prev_consensus:
+ nodes[idhex].flags = prev_consensus[idhex].flags
+
+ true_filt_avg = {}
+ true_strm_avg = {}
+
if cs_junk.bwauth_pid_control:
# Penalize nodes for circuit failure: it indicates CPU pressure
# TODO: Potentially penalize for stream failure, if we run into
# socket exhaustion issues..
plog("INFO", "PID control enabled")
- true_filt_avg = sum(map(lambda n: n.filt_bw*(1.0-n.circ_fail_rate),
- nodes.itervalues()))/float(len(nodes))
- true_strm_avg = sum(map(lambda n: n.strm_bw*(1.0-n.circ_fail_rate),
- nodes.itervalues()))/float(len(nodes))
+
+ if cs_junk.group_by_class:
+ for c in ["Guard+Exit", "Guard", "Exit", "Middle"]:
+ c_nodes = filter(lambda n: n.node_class() == c, nodes.itervalues())
+ true_filt_avg[c] = sum(map(lambda n: n.filt_bw*(1.0-n.circ_fail_rate),
+ c_nodes))/float(len(c_nodes))
+ true_strm_avg[c] = sum(map(lambda n: n.strm_bw*(1.0-n.circ_fail_rate),
+ c_nodes))/float(len(c_nodes))
+ plog("INFO", "Network true_filt_avg["+c+"]: "+str(true_filt_avg[c]))
+ else:
+ filt_avg = sum(map(lambda n: n.filt_bw*(1.0-n.circ_fail_rate),
+ nodes.itervalues()))/float(len(nodes))
+ strm_avg = sum(map(lambda n: n.strm_bw*(1.0-n.circ_fail_rate),
+ nodes.itervalues()))/float(len(nodes))
+ for c in ["Guard+Exit", "Guard", "Exit", "Middle"]:
+ true_filt_avg[c] = filt_avg
+ true_strm_avg[c] = strm_avg
else:
plog("INFO", "PID control disabled")
- true_filt_avg = sum(map(lambda n: n.filt_bw,
- nodes.itervalues()))/float(len(nodes))
- true_strm_avg = sum(map(lambda n: n.strm_bw,
+ filt_avg = sum(map(lambda n: n.filt_bw*(1.0-n.circ_fail_rate),
+ nodes.itervalues()))/float(len(nodes))
+ strm_avg = sum(map(lambda n: n.strm_bw*(1.0-n.circ_fail_rate),
nodes.itervalues()))/float(len(nodes))
+ for c in ["Guard+Exit", "Guard", "Exit", "Middle"]:
+ true_filt_avg[c] = filt_avg
+ true_strm_avg[c] = strm_avg
- plog("DEBUG", "Network true_filt_avg: "+str(true_filt_avg))
prev_votes = None
if cs_junk.bwauth_pid_control:
@@ -489,8 +526,8 @@ def main(argv):
tot_net_bw = 0
for n in nodes.itervalues():
- n.fbw_ratio = n.filt_bw/true_filt_avg
- n.sbw_ratio = n.strm_bw/true_strm_avg
+ n.fbw_ratio = n.filt_bw/true_filt_avg[n.node_class()]
+ n.sbw_ratio = n.strm_bw/true_strm_avg[n.node_clasS()]
if cs_junk.bwauth_pid_control:
if cs_junk.use_desc_bw:
@@ -500,9 +537,13 @@ def main(argv):
# Penalize nodes for circ failure rate
if cs_junk.use_best_ratio and n.sbw_ratio > n.fbw_ratio:
- n.pid_error = (n.strm_bw*(1.0-n.circ_fail_rate) - true_strm_avg)/true_strm_avg
+ n.pid_error = (n.strm_bw*(1.0-n.circ_fail_rate) -
+ true_strm_avg[n.node_class()]) \
+ / true_strm_avg[n.node_class()]
else:
- n.pid_error = (n.filt_bw*(1.0-n.circ_fail_rate) - true_filt_avg)/true_filt_avg
+ n.pid_error = (n.filt_bw*(1.0-n.circ_fail_rate) -
+ true_filt_avg[n.node_class()]) \
+ / true_filt_avg[n.node_class()]
if n.idhex in prev_votes.vote_map:
# If there is a new sample, let's use it for all but guards
More information about the tor-commits
mailing list