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

Skip to content

Commit a100a5a

Browse files
committed
Channels are closed responsibly by patterns
Instead of doing horrible __del__ stuff and freezing everything in the gc, and sometimes getting totally absurd errors: -> lets cleanly and explicitly close our channels all the way down.
1 parent dc55b6a commit a100a5a

File tree

4 files changed

+28
-45
lines changed

4 files changed

+28
-45
lines changed

zerorpc/channel.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ def recv_is_supported(self):
5555
def emit_is_supported(self):
5656
return self._events.emit_is_supported
5757

58-
def __del__(self):
59-
self.close()
60-
6158
def close(self):
6259
if self._channel_dispatcher_task:
6360
self._channel_dispatcher_task.kill()
@@ -135,9 +132,6 @@ def recv_is_supported(self):
135132
def emit_is_supported(self):
136133
return self._multiplexer.emit_is_supported
137134

138-
def __del__(self):
139-
self.close()
140-
141135
def close(self):
142136
if self._channel_id is not None:
143137
del self._multiplexer._active_channels[self._channel_id]
@@ -198,9 +192,6 @@ def on_close_if(self):
198192
def on_close_if(self, cb):
199193
self._on_close_if = cb
200194

201-
def __del__(self):
202-
self.close()
203-
204195
def close(self):
205196
if self._recv_task is not None:
206197
self._recv_task.kill()

zerorpc/core.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -240,21 +240,13 @@ def __call__(self, method, *args, **kargs):
240240
self._context.hook_client_before_request(request_event)
241241
bufchan.emit_event(request_event)
242242

243-
try:
244-
if kargs.get('async', False) is False:
245-
return self._process_response(request_event, bufchan, timeout)
243+
if kargs.get('async', False) is False:
244+
return self._process_response(request_event, bufchan, timeout)
246245

247-
async_result = gevent.event.AsyncResult()
248-
gevent.spawn(self._process_response, request_event, bufchan,
249-
timeout).link(async_result)
250-
return async_result
251-
except:
252-
# XXX: This is going to be closed twice if async is false and
253-
# _process_response raises an exception. I wonder if the above
254-
# async branch can raise an exception too, if no we can just remove
255-
# this code.
256-
bufchan.close()
257-
raise
246+
async_result = gevent.event.AsyncResult()
247+
gevent.spawn(self._process_response, request_event, bufchan,
248+
timeout).link(async_result)
249+
return async_result
258250

259251
def __getattr__(self, method):
260252
return lambda *args, **kargs: self(method, *args, **kargs)

zerorpc/heartbeat.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ def recv_is_supported(self):
5757
def emit_is_supported(self):
5858
return self._channel.emit_is_supported
5959

60-
def __del__(self):
61-
self.close()
62-
6360
def close(self):
6461
if self._heartbeat_task is not None:
6562
self._heartbeat_task.kill()

zerorpc/patterns.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ def accept_answer(self, event):
3838

3939
def process_answer(self, context, channel, req_event, rep_event,
4040
handle_remote_error):
41-
if rep_event.name == 'ERR':
42-
exception = handle_remote_error(rep_event)
43-
context.hook_client_after_request(req_event, rep_event, exception)
44-
raise exception
45-
context.hook_client_after_request(req_event, rep_event)
46-
channel.close()
47-
result = rep_event.args[0]
48-
return result
41+
try:
42+
if rep_event.name == 'ERR':
43+
exception = handle_remote_error(rep_event)
44+
context.hook_client_after_request(req_event, rep_event, exception)
45+
raise exception
46+
context.hook_client_after_request(req_event, rep_event)
47+
return rep_event.args[0]
48+
finally:
49+
channel.close()
4950

5051

5152
class ReqStream:
@@ -74,17 +75,19 @@ def is_stream_done(rep_event):
7475
channel.on_close_if = is_stream_done
7576

7677
def iterator(req_event, rep_event):
77-
while rep_event.name == 'STREAM':
78-
# Like in process_call, we made the choice to call the
79-
# after_exec hook only when the stream is done.
80-
yield rep_event.args
81-
rep_event = channel.recv()
82-
if rep_event.name == 'ERR':
83-
exception = handle_remote_error(rep_event)
84-
context.hook_client_after_request(req_event, rep_event, exception)
85-
raise exception
86-
context.hook_client_after_request(req_event, rep_event)
87-
channel.close()
78+
try:
79+
while rep_event.name == 'STREAM':
80+
# Like in process_call, we made the choice to call the
81+
# after_exec hook only when the stream is done.
82+
yield rep_event.args
83+
rep_event = channel.recv()
84+
if rep_event.name == 'ERR':
85+
exception = handle_remote_error(rep_event)
86+
context.hook_client_after_request(req_event, rep_event, exception)
87+
raise exception
88+
context.hook_client_after_request(req_event, rep_event)
89+
finally:
90+
channel.close()
8891

8992
return iterator(req_event, rep_event)
9093

0 commit comments

Comments
 (0)