[tor-commits] [nyx/master] Centralize pausing in Controller
atagar at torproject.org
atagar at torproject.org
Fri Jul 15 17:33:39 UTC 2016
commit e7385ff70800c162699c72de30822139b053982e
Author: Damian Johnson <atagar at torproject.org>
Date: Thu Jul 14 10:24:59 2016 -0700
Centralize pausing in Controller
Pausing is a global state. We never pause only some of our interface, as such
this belongs in the Controller. There's a couple panels that need special
handling but otherwise a pretty straight forward move.
---
nyx/controller.py | 42 +++++++++++++++++++++++++++++++++---------
nyx/panel/__init__.py | 42 ++++--------------------------------------
nyx/panel/connection.py | 6 ++++--
nyx/panel/graph.py | 12 +++++++-----
nyx/panel/header.py | 5 +++--
nyx/panel/log.py | 5 ++---
test/panel/header.py | 1 +
7 files changed, 54 insertions(+), 59 deletions(-)
diff --git a/nyx/controller.py b/nyx/controller.py
index 964e27d..fc38185 100644
--- a/nyx/controller.py
+++ b/nyx/controller.py
@@ -120,7 +120,8 @@ class Controller(object):
self.quit_signal = False
self._page = 0
- self._is_paused = False
+ self._paused = False
+ self._pause_time = -1
self._force_redraw = False
self._last_drawn = 0
@@ -171,23 +172,46 @@ class Controller(object):
def is_paused(self):
"""
- True if the interface is paused, false otherwise.
+ Provides if the interface is configured to be paused or not.
+
+ :returns: **True** if the interface is paused and **False** otherwise
"""
- return self._is_paused
+ return self._paused
def set_paused(self, is_pause):
"""
- Sets the interface to be paused or unpaused.
+ Pauses or unpauses the interface.
+
+ :param bool is_pause: suspends the interface if **True**, resumes it
+ otherwise
"""
- if is_pause != self._is_paused:
- self._is_paused = is_pause
- self._force_redraw = True
- self.header_panel().redraw()
+ if is_pause != self._paused:
+ if is_pause:
+ self._pause_time = time.time()
+
+ # Couple panels have their own pausing behavior. I'll later change this to
+ # a listener approach or someting else that's less hacky.
for panel_impl in self.get_all_panels():
- panel_impl.set_paused(is_pause)
+ if isinstance(panel_impl, nyx.panel.graph.GraphPanel) or isinstance(panel_impl, nyx.panel.log.LogPanel):
+ panel_impl.set_paused(is_pause)
+
+ self._paused = is_pause
+
+ for panel_impl in self.get_display_panels():
+ panel_impl.redraw()
+
+ def get_pause_time(self):
+ """
+ Provides the time that we were last paused, returning -1 if we've never
+ been paused.
+
+ :returns: **float** with the unix timestamp for when we were last paused
+ """
+
+ return self._pause_time
def header_panel(self):
return self._header_panel
diff --git a/nyx/panel/__init__.py b/nyx/panel/__init__.py
index ee938dc..1d6ae9f 100644
--- a/nyx/panel/__init__.py
+++ b/nyx/panel/__init__.py
@@ -72,9 +72,6 @@ class Panel(object):
def __init__(self):
self._visible = False
- self._paused = False
- self._pause_time = -1
-
self._top = 0
self._left = 0
self._height = -1
@@ -90,40 +87,6 @@ class Panel(object):
self._visible = is_visible
- def is_paused(self):
- """
- Provides if the panel's configured to be paused or not.
- """
-
- return self._paused
-
- def set_paused(self, is_pause):
- """
- Toggles if the panel is paused or not. This causes the panel to be redrawn
- when toggling is pause state unless told to do otherwise. This is
- important when pausing since otherwise the panel's display could change
- when redrawn for other reasons.
-
- Arguments:
- is_pause - freezes the state of the pause attributes if true, makes
- them editable otherwise
- """
-
- if is_pause != self._paused:
- if is_pause:
- self._pause_time = time.time()
-
- self._paused = is_pause
- self.redraw()
-
- def get_pause_time(self):
- """
- Provides the time that we were last paused, returning -1 if we've never
- been paused.
- """
-
- return self._pause_time
-
def get_top(self):
"""
Provides the top position used for subwindows.
@@ -234,10 +197,13 @@ class DaemonPanel(Panel, threading.Thread):
Performs our _update() action at the given rate.
"""
+ import nyx.controller
+
last_ran = -1
+ nyx_controller = nyx.controller.get_controller()
while not self._halt:
- if self.is_paused() or (time.time() - last_ran) < self._update_rate:
+ if nyx_controller.is_paused() or (time.time() - last_ran) < self._update_rate:
with self._pause_condition:
if not self._halt:
self._pause_condition.wait(0.2)
diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py
index 8e032e6..bd78a9b 100644
--- a/nyx/panel/connection.py
+++ b/nyx/panel/connection.py
@@ -11,6 +11,7 @@ import collections
import curses
import itertools
+import nyx.controller
import nyx.curses
import nyx.panel
import nyx.popups
@@ -401,6 +402,7 @@ class ConnectionPanel(nyx.panel.DaemonPanel):
def draw(self, subwindow):
controller = tor_controller()
+ nyx_controller = nyx.controller.get_controller()
entries = self._entries
lines = list(itertools.chain.from_iterable([entry.get_lines() for entry in entries]))
@@ -408,8 +410,8 @@ class ConnectionPanel(nyx.panel.DaemonPanel):
details_offset = DETAILS_HEIGHT + 1 if is_showing_details else 0
selected, scroll = self._scroller.selection(lines, subwindow.height - details_offset - 1)
- if self.is_paused():
- current_time = self.get_pause_time()
+ if nyx_controller.is_paused():
+ current_time = nyx_controller.get_pause_time()
elif not controller.is_alive():
current_time = controller.connection_time()
else:
diff --git a/nyx/panel/graph.py b/nyx/panel/graph.py
index 029f417..e5f9cc7 100644
--- a/nyx/panel/graph.py
+++ b/nyx/panel/graph.py
@@ -481,8 +481,9 @@ class GraphPanel(nyx.panel.Panel):
if not self.displayed_stat:
return 0
+ nyx_controller = nyx.controller.get_controller()
height = DEFAULT_CONTENT_HEIGHT + self._graph_height
- accounting_stats = self._accounting_stats if self.is_paused() else self._accounting_stats_paused
+ accounting_stats = self._accounting_stats if nyx_controller.is_paused() else self._accounting_stats_paused
if self.displayed_stat == GraphStat.BANDWIDTH and accounting_stats:
height += 3
@@ -556,13 +557,13 @@ class GraphPanel(nyx.panel.Panel):
self._accounting_stats_paused = copy.copy(self._accounting_stats)
self._stats_paused = dict([(key, type(self._stats[key])(self._stats[key])) for key in self._stats])
- nyx.panel.Panel.set_paused(self, is_pause)
-
def draw(self, subwindow):
if not self.displayed_stat:
return
- if not self.is_paused():
+ nyx_controller = nyx.controller.get_controller()
+
+ if not nyx_controller.is_paused():
stat = self._stats[self.displayed_stat]
accounting_stats = self._accounting_stats
else:
@@ -586,10 +587,11 @@ class GraphPanel(nyx.panel.Panel):
if not CONFIG['features.graph.bw.accounting.show']:
self._accounting_stats = None
elif not self._accounting_stats or time.time() - self._accounting_stats.retrieved >= ACCOUNTING_RATE:
+ nyx_controller = nyx.controller.get_controller()
old_accounting_stats = self._accounting_stats
self._accounting_stats = tor_controller().get_accounting_stats(None)
- if not self.is_paused():
+ if not nyx_controller.is_paused():
# if we either added or removed accounting info then redraw the whole
# screen to account for resizing
diff --git a/nyx/panel/header.py b/nyx/panel/header.py
index a2a5ae7..5f33f4f 100644
--- a/nyx/panel/header.py
+++ b/nyx/panel/header.py
@@ -148,9 +148,10 @@ class HeaderPanel(nyx.panel.DaemonPanel):
# space available for content
+ nyx_controller = nyx.controller.get_controller()
left_width = max(subwindow.width / 2, 77) if is_wide else subwindow.width
right_width = subwindow.width - left_width
- pause_time = self.get_pause_time() if self.is_paused() else None
+ pause_time = nyx_controller.get_pause_time() if nyx_controller.is_paused() else None
_draw_platform_section(subwindow, 0, 0, left_width, vals)
@@ -175,7 +176,7 @@ class HeaderPanel(nyx.panel.DaemonPanel):
_draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals)
_draw_flags(subwindow, 0, 4, vals.flags)
- _draw_status(subwindow, 0, self.get_height() - 1, self.is_paused(), self._message, *self._message_attr)
+ _draw_status(subwindow, 0, self.get_height() - 1, nyx_controller.is_paused(), self._message, *self._message_attr)
def reset_listener(self, controller, event_type, _):
self._update()
diff --git a/nyx/panel/log.py b/nyx/panel/log.py
index 81b7a64..02cd7fe 100644
--- a/nyx/panel/log.py
+++ b/nyx/panel/log.py
@@ -250,17 +250,16 @@ class LogPanel(nyx.panel.DaemonPanel):
if is_pause:
self._event_log_paused = self._event_log.clone()
- nyx.panel.Panel.set_paused(self, is_pause)
-
def draw(self, subwindow):
scroll = self._scroller.location(self._last_content_height, subwindow.height - 1)
+ nyx_controller = nyx.controller.get_controller()
event_filter = self._filter.clone()
event_types = list(self._event_types)
last_content_height = self._last_content_height
show_duplicates = self._show_duplicates
- event_log = self._event_log_paused if self.is_paused() else self._event_log
+ event_log = self._event_log_paused if nyx_controller.is_paused() else self._event_log
event_log = filter(lambda entry: event_filter.match(entry.display_message), event_log)
event_log = filter(lambda entry: not entry.is_duplicate or show_duplicates, event_log)
diff --git a/test/panel/header.py b/test/panel/header.py
index 3e47afa..c14b404 100644
--- a/test/panel/header.py
+++ b/test/panel/header.py
@@ -73,6 +73,7 @@ class TestHeaderPanel(unittest.TestCase):
@patch('nyx.panel.header.tor_controller')
@patch('nyx.panel.header.Sampling.create')
def test_rendering_panel(self, sampling_mock, tor_controller_mock, nyx_controller_mock):
+ nyx_controller_mock().is_paused.return_value = False
nyx_controller_mock().get_page.return_value = 1
nyx_controller_mock().get_page_count.return_value = 4
sampling_mock.return_value = test_sampling()
More information about the tor-commits
mailing list