From 831ec27bfca3da8571d9a4bd9ef6d5a37fc3ef60 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 26 Nov 2020 13:00:49 +0000 Subject: [PATCH 1/3] Add explicit Pingee connect and disconnect methods --- traits_futures/message_router.py | 9 ++++----- traits_futures/null/pinger.py | 13 ++++++++++++- traits_futures/qt/pinger.py | 12 ++++++++++++ traits_futures/tests/test_pinger.py | 15 ++++++++++----- traits_futures/wx/pinger.py | 16 +++++++++++----- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/traits_futures/message_router.py b/traits_futures/message_router.py index 9ca7d3f6..b2e4db44 100644 --- a/traits_futures/message_router.py +++ b/traits_futures/message_router.py @@ -69,13 +69,15 @@ def connect(self): """ Prepare router for routing. """ - pass + self._pingee = Pingee(on_ping=self._route_message) + self._pingee.connect() def disconnect(self): """ Undo any connections made by the ``connect`` call. """ - pass + self._pingee.disconnect() + self._pingee = None # Private traits ########################################################## @@ -110,6 +112,3 @@ def __message_queue_default(self): def __connection_ids_default(self): return itertools.count() - - def __pingee_default(self): - return Pingee(on_ping=self._route_message) diff --git a/traits_futures/null/pinger.py b/traits_futures/null/pinger.py index 59a1e155..b591198c 100644 --- a/traits_futures/null/pinger.py +++ b/traits_futures/null/pinger.py @@ -30,9 +30,20 @@ class Pingee: """ def __init__(self, on_ping): - self._event_loop = asyncio.get_event_loop() self._on_ping = on_ping + def connect(self): + """ + Prepare Pingee to receive pings. + """ + self._event_loop = asyncio.get_event_loop() + + def disconnect(self): + """ + Undo any connections made in the connect method. + """ + del self._event_loop + class Pinger: """ diff --git a/traits_futures/qt/pinger.py b/traits_futures/qt/pinger.py index b510eeb5..7fc58cb7 100644 --- a/traits_futures/qt/pinger.py +++ b/traits_futures/qt/pinger.py @@ -45,6 +45,18 @@ def __init__(self, on_ping): def _execute_ping_callback(self): self._on_ping() + def connect(self): + """ + Prepare Pingee to receive pings. + """ + pass + + def disconnect(self): + """ + Undo any connections made in the connect method. + """ + pass + class Pinger: """ diff --git a/traits_futures/tests/test_pinger.py b/traits_futures/tests/test_pinger.py index b00649fb..b15d5936 100644 --- a/traits_futures/tests/test_pinger.py +++ b/traits_futures/tests/test_pinger.py @@ -95,21 +95,26 @@ class PingListener(HasStrictTraits): #: Total number of pings received. ping_count = Int(0) + def connect(self): + self.pingee = Pingee(on_ping=lambda: setattr(self, "ping", True)) + self.pingee.connect() + + def disconnect(self): + self.pingee.disconnect() + self.pingee = None + def _ping_fired(self): self.ping_count += 1 - def _pingee_default(self): - return Pingee( - on_ping=lambda: setattr(self, "ping", True), - ) - class TestPinger(GuiTestAssistant, unittest.TestCase): def setUp(self): GuiTestAssistant.setUp(self) self.listener = PingListener() + self.listener.connect() def tearDown(self): + self.listener.disconnect() del self.listener GuiTestAssistant.tearDown(self) diff --git a/traits_futures/wx/pinger.py b/traits_futures/wx/pinger.py index b48eb863..11a69a6f 100644 --- a/traits_futures/wx/pinger.py +++ b/traits_futures/wx/pinger.py @@ -76,12 +76,18 @@ class Pingee(wx.EvtHandler): def __init__(self, on_ping): wx.EvtHandler.__init__(self) - self._on_ping = on_ping + self._on_ping = lambda event: on_ping() + + def connect(self): + """ + Prepare Pingee to receive pings. + """ self._binder = wx.PyEventBinder(_PING_EVENT_TYPE) - self.Bind(self._binder, self._on_ping_event) + self.Bind(self._binder, self._on_ping) - def _on_ping_event(self, event): + def disconnect(self): """ - Handler for events of type _PING_EVENT_TYPE. + Undo any connections made in the connect method. """ - self._on_ping() + self.Unbind(self._binder, handler=self._on_ping) + del self._binder From 5f24c1066a90175c6717e80520fdda95d192f801 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 27 Nov 2020 10:21:57 +0000 Subject: [PATCH 2/3] Update tests --- traits_futures/tests/test_pinger.py | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/traits_futures/tests/test_pinger.py b/traits_futures/tests/test_pinger.py index a7de4ded..91ec6224 100644 --- a/traits_futures/tests/test_pinger.py +++ b/traits_futures/tests/test_pinger.py @@ -102,6 +102,13 @@ class PingListener(HasStrictTraits): #: Total number of pings received. ping_count = Int(0) + def __enter__(self): + self.connect() + return self + + def __exit__(self, *exc_info): + self.disconnect() + def connect(self): self.pingee = Pingee(on_ping=lambda: setattr(self, "ping", True)) self.pingee.connect() @@ -183,18 +190,17 @@ def test_multiple_background_pingers(self): self.assertEqual(self.listener.ping_count, 15) def test_multiple_pingees(self): - listener1 = PingListener() - listener2 = PingListener() - listeners = MultipleListeners(listeners=[listener1, listener2]) - - with BackgroundPinger(listener1.pingee) as pinger1: - with BackgroundPinger(listener2.pingee) as pinger2: - pinger1.ping(3) - pinger2.ping(4) - - self.run_until( - listeners, "ping", lambda obj: obj.ping_count >= 7 - ) + with PingListener() as listener1: + with PingListener() as listener2: + listeners = MultipleListeners(listeners=[listener1, listener2]) + with BackgroundPinger(listener1.pingee) as pinger1: + with BackgroundPinger(listener2.pingee) as pinger2: + pinger1.ping(3) + pinger2.ping(4) + + self.run_until( + listeners, "ping", lambda obj: obj.ping_count >= 7 + ) self.assertEqual(listener1.ping_count, 3) self.assertEqual(listener2.ping_count, 4) From 673263eda27032cc2e6ef098e3ddddf596d82212 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 27 Nov 2020 10:47:31 +0000 Subject: [PATCH 3/3] Update Pinger and Pingee docstrings --- traits_futures/null/pinger.py | 16 ++++++++++++---- traits_futures/qt/pinger.py | 16 ++++++++++++---- traits_futures/wx/pinger.py | 12 ++++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/traits_futures/null/pinger.py b/traits_futures/null/pinger.py index b591198c..8da4aed5 100644 --- a/traits_futures/null/pinger.py +++ b/traits_futures/null/pinger.py @@ -22,11 +22,18 @@ class Pingee: """ Receiver for pings. + Whenever a ping is received from a linked Pingee, the receiver + calls the given fixed parameterless callable. + + The ping receiver must be connected (using the ``connect``) method + before use, and should call ``disconnect`` when it's no longer + expected to receive pings. + Parameters ---------- on_ping : callable - Zero-argument callable that's executed on the main thread as a - result of each ping. + Zero-argument callable that's called on the main thread + every time a ping is received. """ def __init__(self, on_ping): @@ -47,12 +54,13 @@ def disconnect(self): class Pinger: """ - Ping emitter, which can emit pings in a thread-safe manner. + Ping emitter, which can send pings to a receiver in a thread-safe manner. Parameters ---------- pingee : Pingee - The corresponding ping receiver. + The target receiver for the pings. The receiver must already be + connected. """ def __init__(self, pingee): diff --git a/traits_futures/qt/pinger.py b/traits_futures/qt/pinger.py index 7fc58cb7..ef435a33 100644 --- a/traits_futures/qt/pinger.py +++ b/traits_futures/qt/pinger.py @@ -30,11 +30,18 @@ class Pingee(QObject): """ Receiver for pings. + Whenever a ping is received from a linked Pingee, the receiver + calls the given fixed parameterless callable. + + The ping receiver must be connected (using the ``connect``) method + before use, and should call ``disconnect`` when it's no longer + expected to receive pings. + Parameters ---------- on_ping : callable - Zero-argument callable that's executed on the main thread as a - result of each ping. + Zero-argument callable that's called on the main thread + every time a ping is received. """ def __init__(self, on_ping): @@ -60,12 +67,13 @@ def disconnect(self): class Pinger: """ - Ping emitter, which can emit pings in a thread-safe manner. + Ping emitter, which can send pings to a receiver in a thread-safe manner. Parameters ---------- pingee : Pingee - The corresponding ping receiver. + The target receiver for the pings. The receiver must already be + connected. """ def __init__(self, pingee): diff --git a/traits_futures/wx/pinger.py b/traits_futures/wx/pinger.py index 39ba2f22..df65e749 100644 --- a/traits_futures/wx/pinger.py +++ b/traits_futures/wx/pinger.py @@ -24,12 +24,13 @@ class Pinger: """ - Ping emitter, which can emit pings in a thread-safe manner. + Ping emitter, which can send pings to a receiver in a thread-safe manner. Parameters ---------- pingee : Pingee - The corresponding ping receiver. + The target receiver for the pings. The receiver must already be + connected. """ def __init__(self, pingee): @@ -60,6 +61,13 @@ class Pingee(wx.EvtHandler): """ Receiver for pings. + Whenever a ping is received from a linked Pingee, the receiver + calls the given fixed parameterless callable. + + The ping receiver must be connected (using the ``connect``) method + before use, and should call ``disconnect`` when it's no longer + expected to receive pings. + Parameters ---------- on_ping : callable