Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a79a0a5

Browse files
If an on_close_if handler in a BufferedChannel decides to close the
channel, don't try to send any more _zpc_more messages, as they can no longer be sent.
1 parent 85836f3 commit a79a0a5

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

tests/test_buffered_channel.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,61 @@ def _do_with_assert_raises():
444444
client.close()
445445
server_bufchan.close()
446446
server.close()
447+
448+
449+
def test_on_close_if():
450+
"""
451+
Test that the on_close_if method does not cause exceptions when the client
452+
is slow to recv() data.
453+
"""
454+
endpoint = random_ipc_endpoint()
455+
server_events = zerorpc.Events(zmq.ROUTER)
456+
server_events.bind(endpoint)
457+
server = zerorpc.ChannelMultiplexer(server_events)
458+
459+
client_events = zerorpc.Events(zmq.DEALER)
460+
client_events.connect(endpoint)
461+
client = zerorpc.ChannelMultiplexer(client_events, ignore_broadcast=True)
462+
463+
client_channel = client.channel()
464+
client_hbchan = zerorpc.HeartBeatOnChannel(client_channel, freq=2)
465+
client_bufchan = zerorpc.BufferedChannel(client_hbchan, inqueue_size=10)
466+
467+
event = server.recv()
468+
server_channel = server.channel(event)
469+
server_hbchan = zerorpc.HeartBeatOnChannel(server_channel, freq=2)
470+
server_bufchan = zerorpc.BufferedChannel(server_hbchan, inqueue_size=10)
471+
472+
seen = []
473+
474+
def is_stream_done(event):
475+
return event.name == 'done'
476+
477+
def client_do():
478+
while True:
479+
event = client_bufchan.recv()
480+
if event.name == 'done':
481+
return
482+
seen.append(event.args)
483+
gevent.sleep(0.1)
484+
485+
def server_do():
486+
for i in range(0, 10):
487+
server_bufchan.emit('blah', (i))
488+
server_bufchan.emit('done', ('bye'))
489+
490+
client_bufchan.on_close_if = is_stream_done
491+
492+
coro_pool = gevent.pool.Pool()
493+
g1 = coro_pool.spawn(client_do)
494+
g2 = coro_pool.spawn(server_do)
495+
496+
g1.get() # Re-raise any exceptions...
497+
g2.get()
498+
499+
assert seen == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
500+
501+
client_bufchan.close()
502+
server_bufchan.close()
503+
client.close()
504+
server.close()

zerorpc/channel.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,10 @@ def _request_data(self):
254254
self._channel.emit('_zpc_more', (open_slots,))
255255

256256
def recv(self, timeout=None):
257-
if self._verbose:
257+
# self._channel can be set to None by an 'on_close_if' callback if it
258+
# sees a suitable message from the remote end...
259+
#
260+
if self._verbose and self._channel:
258261
if self._input_queue_reserved < self._input_queue_size / 2:
259262
self._request_data()
260263
else:

0 commit comments

Comments
 (0)