# HG changeset patch # User Goffi # Date 1379768301 -7200 # Node ID 36673d19c87e0dd5ba3ee91091a1105582c4ce46 # Parent 4e6467efd6bfe9fe6e9814166126ad90ba378910 server side: better async bridge calls handling diff -r 4e6467efd6bf -r 36673d19c87e libervia.tac --- a/libervia.tac Sat Sep 07 19:54:41 2013 +0200 +++ b/libervia.tac Sat Sep 21 14:58:21 2013 +0200 @@ -29,6 +29,7 @@ from twisted.web.resource import Resource, NoResource from twisted.web.util import Redirect from twisted.python.components import registerAdapter +from twisted.python.failure import Failure from twisted.words.protocols.jabber.jid import JID from txjsonrpc.web import jsonrpc from txjsonrpc import jsonrpclib @@ -122,11 +123,41 @@ del self.waiting_ids[action_tuple] callback(answer_type, action_id, data, *args, **kwargs) -class MethodHandler(jsonrpc.JSONRPC): +class JSONRPCMethodManager(jsonrpc.JSONRPC): def __init__(self, sat_host): jsonrpc.JSONRPC.__init__(self) self.sat_host=sat_host + + def asyncBridgeCall(self, method_name, *args, **kwargs): + """Call an asynchrone bridge method and return a deferred + @param method_name: name of the method as a unicode + @return: a deferred which trigger the result + + """ + d = defer.Deferred() + + def _callback(*args): + if not args: + d.callback(None) + else: + if len(args) != 1: + Exception("Multiple return arguments not supported") + d.callback(args[0]) + + def _errback(result): + d.errback(Failure(unicode(result))) + + kwargs["callback"] = d.callback + kwargs["errback"] = _errback + getattr(self.sat_host.bridge, method_name)(*args, **kwargs) + return d + + +class MethodHandler(JSONRPCMethodManager): + + def __init__(self, sat_host): + JSONRPCMethodManager.__init__(self, sat_host) self.authorized_params = None def render(self, request): @@ -232,8 +263,7 @@ @param max_item: number of items to ask @return list of microblog data (dict)""" profile = ISATSession(self.session).profile - d = defer.Deferred() - self.sat_host.bridge.getLastGroupBlogs(publisher_jid, max_item, profile, callback=d.callback, errback=d.errback) + d = self.asyncBridgeCall("getLastGroupBlogs", publisher_jid, max_item, profile) return d def jsonrpc_getMassiveLastMblogs(self, publishers_type, publishers_list, max_item): @@ -243,8 +273,7 @@ @param max_item: number of items to ask @return: dictionary key=publisher's jid, value=list of microblog data (dict)""" profile = ISATSession(self.session).profile - d = defer.Deferred() - self.sat_host.bridge.getMassiveLastGroupBlogs(publishers_type, publishers_list, max_item, profile, callback=d.callback, errback=d.errback) + d = self.asyncBridgeCall("getMassiveLastGroupBlogs", publishers_type, publishers_list, max_item, profile) self.sat_host.bridge.massiveSubscribeGroupBlogs(publishers_type, publishers_list, profile) return d @@ -254,8 +283,7 @@ @param node: comments node """ profile = ISATSession(self.session).profile - d = defer.Deferred() - self.sat_host.bridge.getGroupBlogComments(service, node, profile, callback=d.callback, errback=d.errback) + d = self.asyncBridgeCall("getGroupBlogComments", service, node, profile) return d @@ -275,8 +303,7 @@ if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost(): error("Trying to get history from a different jid, maybe a hack attempt ?") return {} - d = defer.Deferred() - self.sat_host.bridge.getHistory(from_jid, to_jid, size, between, profile, callback=d.callback, errback=d.errback) + d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, profile) def show(result_dbus): result = [] for line in result_dbus: @@ -362,7 +389,7 @@ def jsonrpc_getParamsUI(self): """Return the parameters XML for profile""" profile = ISATSession(self.session).profile - d = defer.Deferred() + d = self.asyncBridgeCall("getParams", SECURITY_LIMIT, profile) def setAuthorizedParams(d): if self.authorized_params is None: @@ -375,12 +402,12 @@ return d else: return None + d.addCallback(setAuthorizedParams) from sat.tools.xml_tools import paramsXml2xmlUI d.addCallback(lambda d: paramsXml2xmlUI(d) if d else "") - self.sat_host.bridge.getParams(SECURITY_LIMIT, profile, callback=d.callback, errback=d.errback) return d def jsonrpc_setParam(self, name, value, category): @@ -403,13 +430,12 @@ self.sat_host.bridge.chatStateComposing(to_jid_s, profile) -class Register(jsonrpc.JSONRPC): +class Register(JSONRPCMethodManager): """This class manage the registration procedure with SàT It provide an api for the browser, check password and setup the web server""" def __init__(self, sat_host): - jsonrpc.JSONRPC.__init__(self) - self.sat_host=sat_host + JSONRPCMethodManager.__init__(self, sat_host) self.profiles_waiting={} self.request=None @@ -488,8 +514,7 @@ return self.profiles_waiting[_login] = request - d = defer.Deferred() - self.sat_host.bridge.asyncConnect(_login, lambda: d.callback(None), d.errback) + d = self.asyncBridgeCall("asyncConnect", _login) return d def profile_pass_errback(ignore): @@ -497,8 +522,7 @@ request.write("AUTH ERROR") request.finish() - d = defer.Deferred() - self.sat_host.bridge.asyncGetParamA("Password", "Connection", profile_key=_login, callback=d.callback, errback=d.errback) + d = self.asyncBridgeCall("asyncGetParamA", "Password", "Connection", profile_key=_login) d.addCallbacks(profile_pass_cb, profile_pass_errback) return server.NOT_DONE_YET @@ -507,12 +531,10 @@ """Called when a account has just been created, setup stuff has microblog access""" def _connected(ignore): - mblog_d = defer.Deferred() - self.sat_host.bridge.setMicroblogAccess("open", profile, lambda: mblog_d.callback(None), mblog_d.errback) + mblog_d = self.asyncBridgeCall("setMicroblogAccess", "open", profile) mblog_d.addBoth(lambda ignore: self.sat_host.bridge.disconnect(profile)) - d = defer.Deferred() - self.sat_host.bridge.asyncConnect(profile, lambda: d.callback(None), d.errback) + d = self.asyncBridgeCall("asyncConnect", profile) d.addCallback(_connected) def _registerNewAccount(self, request): @@ -551,8 +573,7 @@ request.write('Unknown error (%s)' % reason) request.finish() - d = defer.Deferred() - self.sat_host.bridge.registerSatAccount(email, password, profile, lambda: d.callback(None), d.errback) + d = self.asyncBridgeCall("registerSatAccount", email, password, profile) d.addCallback(registered) d.addErrback(registeringError) return server.NOT_DONE_YET