Skip to content

Commit

Permalink
Add explicit Pingee connect and disconnect methods (#255)
Browse files Browse the repository at this point in the history
* Add explicit Pingee connect and disconnect methods

* Update tests

* Update Pinger and Pingee docstrings
  • Loading branch information
mdickinson authored Nov 27, 2020
1 parent 60efc6c commit df93b11
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 38 deletions.
9 changes: 4 additions & 5 deletions traits_futures/message_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ##########################################################

Expand Down Expand Up @@ -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)
29 changes: 24 additions & 5 deletions traits_futures/null/pinger.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,45 @@ 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):
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:
"""
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):
Expand Down
28 changes: 24 additions & 4 deletions traits_futures/qt/pinger.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -45,15 +52,28 @@ 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:
"""
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):
Expand Down
45 changes: 28 additions & 17 deletions traits_futures/tests/test_pinger.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,24 @@ 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()

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 MultipleListeners(HasStrictTraits):
"""
Expand Down Expand Up @@ -137,8 +147,10 @@ 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)

Expand Down Expand Up @@ -178,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)
Expand Down
27 changes: 20 additions & 7 deletions traits_futures/wx/pinger.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -69,11 +77,16 @@ class Pingee(wx.EvtHandler):

def __init__(self, on_ping):
wx.EvtHandler.__init__(self)
self._on_ping = on_ping
self.Bind(_PingEventBinder, self._on_ping_event)
self._on_ping = lambda event: on_ping()

def _on_ping_event(self, event):
def connect(self):
"""
Prepare Pingee to receive pings.
"""
self.Bind(_PingEventBinder, handler=self._on_ping)

def disconnect(self):
"""
Handler for events of type _PING_EVENT_TYPE.
Undo any connections made in the connect method.
"""
self._on_ping()
self.Unbind(_PingEventBinder, handler=self._on_ping)

0 comments on commit df93b11

Please sign in to comment.