Skip to content

Commit 8630237

Browse files
committed
Add AsyncResult to server as delayed return
1 parent 306d384 commit 8630237

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Test code are available in example directory(bench_client.py and bench_server.py
8484

8585
## TODO
8686

87-
* Add advanced and async return to Server.
87+
* Add advanced return to Server.
8888
* UDP, UNIX Domain support
8989
* Utilities (MultiFuture, SessionPool)
9090
* Support pyev for performance if needed

msgpackrpc/server.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,39 @@ def dispatch(self, method, param, responder):
4545
method = force_str(method)
4646
if not hasattr(self._dispatcher, method):
4747
raise error.NoMethodError("'{0}' method not found".format(method))
48-
responder.set_result(getattr(self._dispatcher, method)(*param))
48+
49+
result = getattr(self._dispatcher, method)(*param)
50+
if isinstance(result, AsyncResult):
51+
result.set_responder(responder)
52+
else:
53+
responder.set_result(result)
4954
except Exception as e:
5055
responder.set_error(str(e))
5156

5257
# TODO: Support advanced and async return
5358

5459

60+
class AsyncResult:
61+
def __init__(self):
62+
self._responder = None
63+
self._result = None
64+
65+
def set_result(self, value, error=None):
66+
if self._responder is not None:
67+
self._responder.set_result(value, error)
68+
else:
69+
self._result = [value, error]
70+
71+
def set_error(self, error, value=None):
72+
self.set_result(value, error)
73+
74+
def set_responder(self, responder):
75+
self._responder = responder
76+
if self._result is not None:
77+
self._responder.set_result(*self._result)
78+
self._result = None
79+
80+
5581
class _Responder:
5682
def __init__(self, sendable, msgid):
5783
self._sendable = sendable

test/test_msgpackrpc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ def long_exec(self):
5858
sleep(3)
5959
return 'finish!'
6060

61+
def async_result(self):
62+
ar = msgpackrpc.server.AsyncResult()
63+
def do_async():
64+
sleep(2)
65+
ar.set_result("You are async!")
66+
threading.Thread(target=do_async).start()
67+
return ar
68+
6169
def setUp(self):
6270
self._address = msgpackrpc.Address('localhost', helper.unused_port())
6371

@@ -146,6 +154,10 @@ def test_unknown_method(self):
146154
message = e.args[0]
147155
self.assertEqual(message, "'unknown' method not found", "Error message mismatched")
148156

157+
def test_async_result(self):
158+
client = self.setup_env();
159+
self.assertEqual(client.call('async_result'), "You are async!")
160+
149161
def test_connect_failed(self):
150162
client = self.setup_env();
151163
client = msgpackrpc.Client(msgpackrpc.Address('localhost', self._address.port - 10), unpack_encoding='utf-8')

0 commit comments

Comments
 (0)