Commit 5ef4f237 authored by Jeremy Hylton's avatar Jeremy Hylton

Extend Delay objects with an error() method that send an exception to

the client.

Also, simplify the test for exceptions received by the client.  If the
class is a subclass of Exception, there's no need to ask if the
instance is of type ClassType.
parent 99d4f275
...@@ -38,26 +38,35 @@ class Delay: ...@@ -38,26 +38,35 @@ class Delay:
the mainloop from sending a response. the mainloop from sending a response.
""" """
def set_sender(self, msgid, send_reply): def set_sender(self, msgid, send_reply, return_error):
self.msgid = msgid self.msgid = msgid
self.send_reply = send_reply self.send_reply = send_reply
self.return_error = return_error
def reply(self, obj): def reply(self, obj):
self.send_reply(self.msgid, obj) self.send_reply(self.msgid, obj)
def error(self, exc_info):
log("Error raised in delayed method", zLOG.ERROR, error=exc_info)
self.return_error(self.msgid, 0, *exc_info[:2])
class MTDelay(Delay): class MTDelay(Delay):
def __init__(self): def __init__(self):
self.ready = threading.Event() self.ready = threading.Event()
def set_sender(self, msgid, send_reply): def set_sender(self, msgid, send_reply, return_error):
Delay.set_sender(self, msgid, send_reply) Delay.set_sender(self, msgid, send_reply, return_error)
self.ready.set() self.ready.set()
def reply(self, obj): def reply(self, obj):
self.ready.wait() self.ready.wait()
Delay.reply(self, obj) Delay.reply(self, obj)
def error(self, exc_info):
self.ready.wait()
Delay.error(self, exc_info)
class Connection(smac.SizedMessageAsyncConnection): class Connection(smac.SizedMessageAsyncConnection):
"""Dispatcher for RPC on object on both sides of socket. """Dispatcher for RPC on object on both sides of socket.
...@@ -227,7 +236,7 @@ class Connection(smac.SizedMessageAsyncConnection): ...@@ -227,7 +236,7 @@ class Connection(smac.SizedMessageAsyncConnection):
if __debug__: if __debug__:
log("%s return %s" % (name, short_repr(ret)), zLOG.DEBUG) log("%s return %s" % (name, short_repr(ret)), zLOG.DEBUG)
if isinstance(ret, Delay): if isinstance(ret, Delay):
ret.set_sender(msgid, self.send_reply) ret.set_sender(msgid, self.send_reply, self.return_error)
else: else:
self.send_reply(msgid, ret) self.send_reply(msgid, ret)
...@@ -296,10 +305,11 @@ class Connection(smac.SizedMessageAsyncConnection): ...@@ -296,10 +305,11 @@ class Connection(smac.SizedMessageAsyncConnection):
self.__reply_lock.acquire() self.__reply_lock.acquire()
assert r_msgid == msgid, "%s != %s: %s" % (r_msgid, msgid, r_args) assert r_msgid == msgid, "%s != %s: %s" % (r_msgid, msgid, r_args)
if type(r_args) == types.TupleType \ if (isinstance(r_args, types.TupleType)
and type(r_args[0]) == types.ClassType \ and issubclass(r_args[0], Exception)):
and issubclass(r_args[0], Exception): inst = r_args[1]
raise r_args[1] # error raised by server raise inst # error raised by server
else:
return r_args return r_args
def callAsync(self, method, *args): def callAsync(self, method, *args):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment