changeset 1108:7ec1ba86d38d

server: replaced blocking calls to bridge by bridgeCall which is not blocking
author Goffi <goffi@goffi.org>
date Mon, 04 Jun 2018 11:52:19 +0200 (2018-06-04)
parents 2066d4fd9036
children 3a7b2b239d3e
files src/server/server.py
diffstat 1 files changed, 43 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/server/server.py	Sun Jun 03 14:04:05 2018 +0200
+++ b/src/server/server.py	Mon Jun 04 11:52:19 2018 +0200
@@ -398,13 +398,14 @@
             return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc'))  # pylint: disable=E1103
         return jsonrpc.JSONRPC.render(self, request)
 
+    @defer.inlineCallbacks
     def jsonrpc_getVersion(self):
         """Return SàT version"""
         try:
-            return self._version_cache
+            defer.returnValue(self._version_cache)
         except AttributeError:
-            self._version_cache = self.sat_host.bridge.getVersion()
-            return self._version_cache
+            self._version_cache = yield self.sat_host.bridgeCall("getVersion")
+            defer.returnValue(self._version_cache)
 
     def jsonrpc_getLiberviaVersion(self):
         """Return Libervia version"""
@@ -414,39 +415,40 @@
         """Disconnect the profile"""
         sat_session = session_iface.ISATSession(self.session)
         profile = sat_session.profile
-        self.sat_host.bridge.disconnect(profile)
+        self.sat_host.bridgeCall("disconnect", profile)
 
     def jsonrpc_getContacts(self):
         """Return all passed args."""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getContacts(profile)
+        return self.sat_host.bridgeCall("getContacts", profile)
 
+    @defer.inlineCallbacks
     def jsonrpc_addContact(self, entity, name, groups):
         """Subscribe to contact presence, and add it to the given groups"""
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.addContact(entity, profile)
-        self.sat_host.bridge.updateContact(entity, name, groups, profile)
+        yield self.sat_host.bridgeCall("addContact", entity, profile)
+        yield self.sat_host.bridgeCall("updateContact", entity, name, groups, profile)
 
     def jsonrpc_delContact(self, entity):
         """Remove contact from contacts list"""
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.delContact(entity, profile)
+        return self.sat_host.bridgeCall("delContact", entity, profile)
 
     def jsonrpc_updateContact(self, entity, name, groups):
         """Update contact's roster item"""
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.updateContact(entity, name, groups, profile)
+        return self.sat_host.bridgeCall("updateContact", entity, name, groups, profile)
 
     def jsonrpc_subscription(self, sub_type, entity):
         """Confirm (or infirm) subscription,
         and setup user roster in case of subscription"""
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.subscription(sub_type, entity, profile)
+        return self.sat_host.bridgeCall("subscription", sub_type, entity, profile)
 
     def jsonrpc_getWaitingSub(self):
         """Return list of room already joined by user"""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getWaitingSub(profile)
+        return self.sat_host.bridgeCall("getWaitingSub", profile)
 
     def jsonrpc_setStatus(self, presence, status):
         """Change the presence and/or status
@@ -454,7 +456,7 @@
         @param status: any string to describe your status
         """
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.setPresence('', presence, {'': status}, profile)
+        return self.sat_host.bridgeCall("setPresence", '', presence, {'': status}, profile)
 
     def jsonrpc_messageSend(self, to_jid, msg, subject, type_, extra={}):
         """send message"""
@@ -540,7 +542,7 @@
         @return (str): RT Deferred session id
         """
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.mbGetFromMany(publishers_type, publishers, max_items, extra, profile)
+        return self.sat_host.bridgeCall("mbGetFromMany", publishers_type, publishers, max_items, extra, profile)
 
     def jsonrpc_mbGetFromManyRTResult(self, rt_session):
         """Get results from RealTime mbGetFromMany session
@@ -563,7 +565,7 @@
         @return (str): RT Deferred session id
         """
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.mbGetFromManyWithComments(publishers_type, publishers, max_items, max_comments, rsm_dict, rsm_comments_dict, profile)
+        return self.sat_host.bridgeCall("mbGetFromManyWithComments", publishers_type, publishers, max_items, max_comments, rsm_dict, rsm_comments_dict, profile)
 
     def jsonrpc_mbGetFromManyWithCommentsRTResult(self, rt_session):
         """Get results from RealTime mbGetFromManyWithComments session
@@ -680,7 +682,7 @@
     def jsonrpc_getPresenceStatuses(self):
         """Get Presence information for connected contacts"""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getPresenceStatuses(profile)
+        return self.sat_host.bridgeCall("getPresenceStatuses", profile)
 
     def jsonrpc_historyGet(self, from_jid, to_jid, size, between, search=''):
         """Return history for the from_jid/to_jid couple"""
@@ -688,8 +690,7 @@
         profile = sat_session.profile
         sat_jid = sat_session.jid
         if not sat_jid:
-            # we keep a session cache for jid to avoir jid spoofing
-            sat_jid = sat_session.jid = jid.JID(self.sat_host.bridge.getParamA("JabberID", "Connection", profile_key=profile))
+            raise exceptions.InternalError('session jid should be set')
         if jid.JID(from_jid).userhost() != sat_jid.userhost() and jid.JID(to_jid).userhost() != sat_jid.userhost():
             log.error(u"Trying to get history from a different jid (given (browser): {}, real (backend): {}), maybe a hack attempt ?".format(from_jid, sat_jid))
             return {}
@@ -725,7 +726,7 @@
         profile = session_iface.ISATSession(self.session).profile
         room_id = room_jid.split("@")[0]
         service = room_jid.split("@")[1]
-        self.sat_host.bridge.inviteMUC(contact_jid, service, room_id, {}, profile)
+        return self.sat_host.bridgeCall("inviteMUC", contact_jid, service, room_id, {}, profile)
 
     def jsonrpc_mucLeave(self, room_jid):
         """Quit a Multi-User Chat room"""
@@ -735,12 +736,12 @@
         except:
             log.warning('Invalid room jid')
             return
-        self.sat_host.bridge.mucLeave(room_jid.userhost(), profile)
+        return self.sat_host.bridgeCall("mucLeave", room_jid.userhost(), profile)
 
     def jsonrpc_mucGetRoomsJoined(self):
         """Return list of room already joined by user"""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.mucGetRoomsJoined(profile)
+        return self.sat_host.bridgeCall("mucGetRoomsJoined", profile)
 
     def jsonrpc_mucGetDefaultService(self):
         """@return: the default MUC"""
@@ -754,7 +755,7 @@
         @param room_jid (unicode): room JID or empty string to generate a unique name
         """
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile)
+        return self.sat_host.bridgeCall("tarotGameLaunch", other_players, room_jid, profile)
 
     def jsonrpc_getTarotCardsPaths(self):
         """Give the path of all the tarot cards"""
@@ -765,12 +766,12 @@
     def jsonrpc_tarotGameReady(self, player, referee):
         """Tell to the server that we are ready to start the game"""
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.tarotGameReady(player, referee, profile)
+        return self.sat_host.bridgeCall("tarotGameReady", player, referee, profile)
 
     def jsonrpc_tarotGamePlayCards(self, player_nick, referee, cards):
         """Tell to the server the cards we want to put on the table"""
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.tarotGamePlayCards(player_nick, referee, cards, profile)
+        return self.sat_host.bridgeCall("tarotGamePlayCards", player_nick, referee, cards, profile)
 
     def jsonrpc_launchRadioCollective(self, invited, room_jid=""):
         """Create a room, invite people, and start a radio collective.
@@ -779,7 +780,7 @@
         @param room_jid (unicode): room JID or empty string to generate a unique name
         """
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile)
+        return self.sat_host.bridgeCall("radiocolLaunch", invited, room_jid, profile)
 
     def jsonrpc_getEntitiesData(self, jids, keys):
         """Get cached data for several entities at once
@@ -791,7 +792,7 @@
             raise exceptions.PermissionError("Trying to access unallowed data (hack attempt ?)")
         profile = session_iface.ISATSession(self.session).profile
         try:
-            return self.sat_host.bridge.getEntitiesData(jids, keys, profile)
+            return self.sat_host.bridgeCall("getEntitiesData", jids, keys, profile)
         except Exception as e:
             raise failure.Failure(jsonrpclib.Fault(C.ERRNUM_BRIDGE_ERRBACK, unicode(e)))
 
@@ -805,7 +806,7 @@
             raise exceptions.PermissionError("Trying to access unallowed data (hack attempt ?)")
         profile = session_iface.ISATSession(self.session).profile
         try:
-            return self.sat_host.bridge.getEntityData(jid, keys, profile)
+            return self.sat_host.bridgeCall("getEntityData", jid, keys, profile)
         except Exception as e:
             raise failure.Failure(jsonrpclib.Fault(C.ERRNUM_BRIDGE_ERRBACK, unicode(e)))
 
@@ -814,7 +815,7 @@
         @param jid_: jid of contact from who we want data
         @return: id to retrieve the profile"""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getCard(jid_, profile)
+        return self.sat_host.bridgeCall("getCard", jid_, profile)
 
     @defer.inlineCallbacks
     def jsonrpc_avatarGet(self, entity, cache_only, hash_only):
@@ -833,7 +834,7 @@
         """Get the dialog for managing user account
         @return: XML string of the XMLUI"""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getAccountDialogUI(profile)
+        return self.sat_host.bridgeCall("getAccountDialogUI", profile)
 
     def jsonrpc_getParamsUI(self):
         """Return the parameters XML for profile"""
@@ -854,7 +855,7 @@
 
     def jsonrpc_setParam(self, name, value, category):
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.setParam(name, value, category, C.SECURITY_LIMIT, profile)
+        return self.sat_host.bridgeCall("setParam", name, value, category, C.SECURITY_LIMIT, profile)
 
     def jsonrpc_launchAction(self, callback_id, data):
         #FIXME: any action can be launched, this can be a huge security issue if callback_id can be guessed
@@ -868,7 +869,7 @@
         @param to_jid_s: contact the user is composing to
         """
         profile = session_iface.ISATSession(self.session).profile
-        self.sat_host.bridge.chatStateComposing(to_jid_s, profile)
+        return self.sat_host.bridgeCall("chatStateComposing", to_jid_s, profile)
 
     def jsonrpc_getNewAccountDomain(self):
         """@return: the domain for new account creation"""
@@ -883,22 +884,22 @@
         @param safe: clean resulting XHTML to avoid malicious code if True (forced here)
         @return: converted text """
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.syntaxConvert(text, syntax_from, syntax_to, True, profile)
+        return self.sat_host.bridgeCall("syntaxConvert", text, syntax_from, syntax_to, True, profile)
 
     def jsonrpc_getLastResource(self, jid_s):
         """Get the last active resource of that contact."""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getLastResource(jid_s, profile)
+        return self.sat_host.bridgeCall("getLastResource", jid_s, profile)
 
     def jsonrpc_getFeatures(self):
         """Return the available features in the backend for profile"""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.getFeatures(profile)
+        return self.sat_host.bridgeCall("getFeatures", profile)
 
     def jsonrpc_skipOTR(self):
         """Tell the backend to leave OTR handling to Libervia."""
         profile = session_iface.ISATSession(self.session).profile
-        return self.sat_host.bridge.skipOTR(profile)
+        return self.sat_host.bridgeCall("skipOTR", profile)
 
     def jsonrpc_namespacesGet(self):
         return self.sat_host.bridgeCall('namespacesGet')
@@ -1077,7 +1078,7 @@
     def jsonrpc_isConnected(self):
         _session = self.request.getSession()
         profile = session_iface.ISATSession(_session).profile
-        return self.sat_host.bridge.isConnected(profile)
+        return self.sat_host.bridgeCall("isConnected", profile)
 
     def jsonrpc_connect(self):
         _session = self.request.getSession()
@@ -1085,7 +1086,7 @@
         if self.waiting_profiles.getRequest(profile):
             raise jsonrpclib.Fault(1, C.ALREADY_WAITING)  # FIXME: define some standard error codes for libervia
         self.waiting_profiles.setRequest(self.request, profile)
-        self.sat_host.bridge.connect(profile)
+        self.sat_host.bridgeCall("connect", profile)
         return server.NOT_DONE_YET
 
     def jsonrpc_getSessionMetadata(self):
@@ -1120,7 +1121,7 @@
     def jsonrpc_menusGet(self):
         """Return the parameters XML for profile"""
         # XXX: we put this method in Register because we get menus before being logged
-        return self.sat_host.bridge.menusGet('', C.SECURITY_LIMIT)
+        return self.sat_host.bridgeCall("menusGet", '', C.SECURITY_LIMIT)
 
     def _getSecurityWarning(self):
         """@return: a security warning message, or None if the connection is secure"""
@@ -1254,11 +1255,12 @@
                 log.error(_(u'Service profile disconnected twice in a short time, please check connection'))
             else:
                 log.info(_(u"Service profile has been disconnected, but we need it! Reconnecting it..."))
-                self.sat_host.bridge.connect(profile,
+                d = self.sat_host.bridgeCall("connect", profile,
                     self.sat_host.options['passphrase'],
                     {},
-                    errback=lambda failure_: log.error(_(u"Can't reconnect service profile, please check connection: {reason}").format(reason=failure_))
                     )
+                d.addErrback(lambda failure_: log.error(_(u"Can't reconnect service profile, please check connection: {reason}").format(
+                    reason=failure_)))
             self._last_service_prof_disconnect = time.time()
             return
 
@@ -2094,12 +2096,13 @@
             else:
                 reactor.listenTCP(self.options['port'], self.site)
 
+    @defer.inlineCallbacks
     def stopService(self):
         log.info(_("launching cleaning methods"))
         for callback, args, kwargs in self._cleanup:
             callback(*args, **kwargs)
         try:
-            self.bridge.disconnect(C.SERVICE_PROFILE)
+            yield self.bridgeCall("disconnect", C.SERVICE_PROFILE)
         except Exception:
             log.warning(u"Can't disconnect service profile")