[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