[tor-commits] [nyx/master] Don't use lru_cache for connection entry attributes

atagar at torproject.org atagar at torproject.org
Sun Oct 22 01:14:57 UTC 2017


commit 52216d6977f44ffa3fa7e406e6bc4a90ec90e86f
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Oct 21 10:37:15 2017 -0700

    Don't use lru_cache for connection entry attributes
    
    Interesting. The lru_cache for from_connection works, but the ones for the
    methods don't. This causes truly horrid performance when you have a ton of
    connections since it's recalculating the type and lines with every redraw.
---
 nyx/panel/connection.py | 47 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py
index 8e5873d..9b3279c 100644
--- a/nyx/panel/connection.py
+++ b/nyx/panel/connection.py
@@ -91,6 +91,11 @@ class Entry(object):
   def from_circuit(circuit):
     return CircuitEntry(circuit)
 
+  def __init__(self):
+    self._lines = None
+    self._type = None
+    self._is_private_val = None
+
   def get_lines(self):
     """
     Provides individual lines of connection information.
@@ -98,7 +103,10 @@ class Entry(object):
     :returns: **list** of **ConnectionLine** concerning this entry
     """
 
-    raise NotImplementedError('should be implemented by subclasses')
+    if self._lines is None:
+      self._lines = self._get_lines()
+
+    return self._lines
 
   def get_type(self):
     """
@@ -107,7 +115,10 @@ class Entry(object):
     :returns: **Category** for the connection's type
     """
 
-    raise NotImplementedError('should be implemented by subclasses')
+    if self._type is None:
+      self._type = self._get_type()
+
+    return self._type
 
   def is_private(self):
     """
@@ -118,7 +129,10 @@ class Entry(object):
     :returns: **bool** indicating if connection information is sensive or not
     """
 
-    raise NotImplementedError('should be implemented by subclasses')
+    if self._is_private_val is None:
+      self._is_private_val = self._is_private()
+
+    return self._is_private_val
 
   def sort_value(self, attr):
     """
@@ -153,13 +167,22 @@ class Entry(object):
     else:
       return ''
 
+  def _get_lines(self):
+    raise NotImplementedError('should be implemented by subclasses')
+
+  def _get_type(self):
+    raise NotImplementedError('should be implemented by subclasses')
+
+  def _is_private(self):
+    raise NotImplementedError('should be implemented by subclasses')
+
 
 class ConnectionEntry(Entry):
   def __init__(self, connection):
+    super(ConnectionEntry, self).__init__()
     self._connection = connection
 
-  @lru_cache()
-  def get_lines(self):
+  def _get_lines(self):
     fingerprint, nickname, locale = None, None, None
 
     if self.get_type() in (Category.OUTBOUND, Category.CIRCUIT, Category.DIRECTORY, Category.EXIT):
@@ -171,8 +194,7 @@ class ConnectionEntry(Entry):
 
     return [Line(self, LineType.CONNECTION, self._connection, None, fingerprint, nickname, locale)]
 
-  @lru_cache()
-  def get_type(self):
+  def _get_type(self):
     controller = tor_controller()
 
     if self._connection.local_port in controller.get_ports(Listener.OR, []):
@@ -201,8 +223,7 @@ class ConnectionEntry(Entry):
 
     return Category.OUTBOUND
 
-  @lru_cache()
-  def is_private(self):
+  def _is_private(self):
     if not CONFIG['show_addresses']:
       return True
 
@@ -222,10 +243,10 @@ class ConnectionEntry(Entry):
 
 class CircuitEntry(Entry):
   def __init__(self, circuit):
+    super(CircuitEntry, self).__init__()
     self._circuit = circuit
 
-  @lru_cache()
-  def get_lines(self):
+  def _get_lines(self):
     def line(fingerprint, line_type):
       address, port, nickname, locale = '0.0.0.0', 0, None, None
       consensus_tracker = nyx.tracker.get_consensus_tracker()
@@ -241,10 +262,10 @@ class CircuitEntry(Entry):
     header_line = line(self._circuit.path[-1][0] if self._circuit.status == 'BUILT' else None, LineType.CIRCUIT_HEADER)
     return [header_line] + [line(fp, LineType.CIRCUIT) for fp, _ in self._circuit.path]
 
-  def get_type(self):
+  def _get_type(self):
     return Category.CIRCUIT
 
-  def is_private(self):
+  def _is_private(self):
     return False
 
 





More information about the tor-commits mailing list