commit 964e9a7afb7acee0351c7ba23579b5b5efdf640b Author: Damian Johnson atagar@torproject.org Date: Sun Oct 22 10:38:35 2017 -0700
Manually handle caching of connections
Connections shouldn't use a lru_cache. If the cache size is less than the number of connections we have at any point then we consume extra cpu, but if it's too high we consume more and more memory unnecessarily until it's filled.
Instead evicting from the cache when a connection hasn't been referenced in a while. --- nyx/panel/connection.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py index 9b3279c..3fe283b 100644 --- a/nyx/panel/connection.py +++ b/nyx/panel/connection.py @@ -23,12 +23,6 @@ from nyx.menu import MenuItem, Submenu, RadioMenuItem, RadioGroup from stem.control import Listener from stem.util import datetime_to_unix, conf, connection, enum, str_tools
-try: - # added in python 3.2 - from functools import lru_cache -except ImportError: - from stem.util.lru_cache import lru_cache - # height of the detail panel content, not counting top and bottom border
DETAILS_HEIGHT = 7 @@ -41,6 +35,9 @@ UPDATE_RATE = 5 # rate in seconds at which we refresh LAST_RETRIEVED_HS_CONF = None LAST_RETRIEVED_CIRCUITS = None
+ENTRY_CACHE = {} +ENTRY_CACHE_REFERENCED = {} + # Connection Categories: # Inbound Relay connection, coming to us. # Outbound Relay connection, leaving us. @@ -82,14 +79,20 @@ CONFIG = conf.config_dict('nyx', {
class Entry(object): @staticmethod - @lru_cache(maxsize = 10000) def from_connection(connection): - return ConnectionEntry(connection) + if connection not in ENTRY_CACHE: + ENTRY_CACHE[connection] = ConnectionEntry(connection) + + ENTRY_CACHE_REFERENCED[connection] = time.time() + return ENTRY_CACHE[connection]
@staticmethod - @lru_cache() def from_circuit(circuit): - return CircuitEntry(circuit) + if circuit not in ENTRY_CACHE: + ENTRY_CACHE[circuit] = CircuitEntry(circuit) + + ENTRY_CACHE_REFERENCED[circuit] = time.time() + return ENTRY_CACHE[circuit]
def __init__(self): self._lines = None @@ -551,6 +554,18 @@ class ConnectionPanel(nyx.panel.DaemonPanel):
nyx.tracker.get_port_usage_tracker().query(local_ports, remote_ports)
+ # clear cache of anything that hasn't been referenced in the last five minutes + + now = time.time() + to_clear = [k for k, v in ENTRY_CACHE_REFERENCED.items() if (now - v) >= 300] + + for entry in to_clear: + for cache in (ENTRY_CACHE, ENTRY_CACHE_REFERENCED): + try: + del cache[entry] + except KeyError: + pass + self.redraw()
tor-commits@lists.torproject.org