[tor-commits] [arm/master] Use GraphStat constructor to clone
atagar at torproject.org
atagar at torproject.org
Mon Oct 20 01:17:33 UTC 2014
commit fd8c546282aa5b85fbc9dd74765ebf6e6bc126a2
Author: Damian Johnson <atagar at torproject.org>
Date: Sun Oct 19 14:33:02 2014 -0700
Use GraphStat constructor to clone
Common pattern among classes is for the constructor to clone if given an
instance of its own type. For example, dict(my_dict) makes a shallow copy.
Doing this for our GraphStats rather than having a custom clone() method.
---
arm/graph_panel.py | 133 ++++++++++++++++++++++------------------------------
1 file changed, 55 insertions(+), 78 deletions(-)
diff --git a/arm/graph_panel.py b/arm/graph_panel.py
index f76df9a..1b3158c 100644
--- a/arm/graph_panel.py
+++ b/arm/graph_panel.py
@@ -128,51 +128,38 @@ class Stat(object):
self._in_process_value[interval] = 0
-class GraphStats:
+class GraphStats(object):
"""
Module that's expected to update dynamically and provide attributes to be
graphed. Up to two graphs (a 'primary' and 'secondary') can be displayed at a
time and timescale parameters use the labels defined in CONFIG['attr.graph.intervals'].
"""
- def __init__(self):
+ def __init__(self, clone = None):
"""
Initializes parameters needed to present a graph.
"""
- # panel to be redrawn when updated (set when added to GraphPanel)
-
- self._graph_panel = None
- self.title = ''
- self.title_stats = []
- self.is_selected = False
- self.is_pause_buffer = False
-
- self.primary = Stat()
- self.secondary = Stat()
-
- # tracks BW events
-
- tor_controller().add_event_listener(self.bandwidth_event, stem.control.EventType.BW)
-
- def clone(self, new_copy=None):
- """
- Provides a deep copy of this instance.
+ if clone:
+ self.title = clone.title
+ self.title_stats = list(clone.title_stats)
+ self.is_selected = clone.is_selected
+ self.is_pause_buffer = True
- Arguments:
- new_copy - base instance to build copy off of
- """
+ self.primary = Stat(clone.primary)
+ self.secondary = Stat(clone.secondary)
+ else:
+ self.title = ''
+ self.title_stats = []
+ self.is_selected = False
+ self.is_pause_buffer = False
- if not new_copy:
- new_copy = GraphStats()
+ self.primary = Stat()
+ self.secondary = Stat()
- new_copy.title = self.title
- new_copy.title_stats = list(self.title_stats)
- new_copy.primary = Stat(self.primary)
- new_copy.secondary = Stat(self.secondary)
+ tor_controller().add_event_listener(self.bandwidth_event, stem.control.EventType.BW)
- new_copy.is_pause_buffer = True
- return new_copy
+ self._graph_panel = None
def event_tick(self):
"""
@@ -224,43 +211,40 @@ class BandwidthStats(GraphStats):
Uses tor BW events to generate bandwidth usage graph.
"""
- def __init__(self, is_pause_buffer = False):
- GraphStats.__init__(self)
- self.title = 'Bandwidth'
-
- # listens for tor reload (sighup) events which can reset the bandwidth
- # rate/burst
+ def __init__(self, clone = None):
+ GraphStats.__init__(self, clone)
- controller = tor_controller()
+ if clone:
+ self.start_time = clone.start_time
+ else:
+ self.title = 'Bandwidth'
- if not is_pause_buffer:
- self.reset_listener(controller, State.INIT, None) # initializes values
+ # listens for tor reload (sighup) events which can reset the bandwidth
+ # rate/burst
- controller.add_status_listener(self.reset_listener)
- self.new_desc_event(None) # updates title params
+ controller = tor_controller()
- # We both show our 'total' attributes and use it to determine our average.
- #
- # If we can get *both* our start time and the totals from tor (via 'GETINFO
- # traffic/*') then that's ideal, but if not then just track the total for
- # the time arm is run.
+ self.reset_listener(controller, State.INIT, None) # initializes values
- read_total = controller.get_info('traffic/read', None)
- write_total = controller.get_info('traffic/written', None)
- start_time = system.start_time(controller.get_pid(None))
+ controller.add_status_listener(self.reset_listener)
+ self.new_desc_event(None) # updates title params
- if read_total and write_total and start_time:
- self.primary.total = int(read_total) / 1024 # Bytes -> KB
- self.secondary.total = int(write_total) / 1024 # Bytes -> KB
- self.start_time = start_time
- else:
- self.start_time = time.time()
+ # We both show our 'total' attributes and use it to determine our average.
+ #
+ # If we can get *both* our start time and the totals from tor (via 'GETINFO
+ # traffic/*') then that's ideal, but if not then just track the total for
+ # the time arm is run.
- def clone(self, new_copy = None):
- if not new_copy:
- new_copy = BandwidthStats(True)
+ read_total = controller.get_info('traffic/read', None)
+ write_total = controller.get_info('traffic/written', None)
+ start_time = system.start_time(controller.get_pid(None))
- return GraphStats.clone(self, new_copy)
+ if read_total and write_total and start_time:
+ self.primary.total = int(read_total) / 1024 # Bytes -> KB
+ self.secondary.total = int(write_total) / 1024 # Bytes -> KB
+ self.start_time = start_time
+ else:
+ self.start_time = time.time()
def reset_listener(self, controller, event_type, _):
self.new_desc_event(None) # updates title params
@@ -400,15 +384,11 @@ class ConnStats(GraphStats):
outbound. Control connections are excluded from counts.
"""
- def __init__(self):
- GraphStats.__init__(self)
- self.title = 'Connection Count'
-
- def clone(self, new_copy=None):
- if not new_copy:
- new_copy = ConnStats()
+ def __init__(self, clone = None):
+ GraphStats.__init__(self, clone)
- return GraphStats.clone(self, new_copy)
+ if not clone:
+ self.title = 'Connection Count'
def event_tick(self):
"""
@@ -449,16 +429,14 @@ class ResourceStats(GraphStats):
System resource usage tracker.
"""
- def __init__(self):
+ def __init__(self, clone = None):
GraphStats.__init__(self)
- self.title = 'System Resources'
- self._last_counter = None
-
- def clone(self, new_copy=None):
- if not new_copy:
- new_copy = ResourceStats()
- return GraphStats.clone(self, new_copy)
+ if clone:
+ self._last_counter = clone._last_counter
+ else:
+ self.title = 'System Resources'
+ self._last_counter = None
def primary_header(self, width):
avg = self.primary.total / max(1, self.primary.tick)
@@ -902,8 +880,7 @@ class GraphPanel(panel.Panel):
def copy_attr(self, attr):
if attr == 'stats':
- # uses custom clone method to copy GraphStats instances
- return dict([(key, self.stats[key].clone()) for key in self.stats])
+ return dict([(key, type(self.stats[key])(self.stats[key])) for key in self.stats])
else:
return panel.Panel.copy_attr(self, attr)
More information about the tor-commits
mailing list