diff --git a/sat/core/xmpp.py b/sat/core/xmpp.py index eaa5a9d2..854acc54 100644 --- a/sat/core/xmpp.py +++ b/sat/core/xmpp.py @@ -163,103 +163,109 @@ class SatXMPPEntity: raise exceptions.CancelError(f"{profile} is already being connected") cls.profiles_connecting.add(profile) try: - port = int( - host.memory.getParamA( - C.FORCE_PORT_PARAM, "Connection", profile_key=profile - ) - ) - except ValueError: - log.debug(_("Can't parse port value, using default value")) - port = ( - None - ) # will use default value 5222 or be retrieved from a DNS SRV record - - password = await host.memory.asyncGetParamA( - "Password", "Connection", profile_key=profile - ) - - entity_jid_s = await host.memory.asyncGetParamA( - "JabberID", "Connection", profile_key=profile) - entity_jid = jid.JID(entity_jid_s) - - if not entity_jid.resource and not cls.is_component and entity_jid.user: - # if no resource is specified, we create our own instead of using - # server returned one, as it will then stay stable in case of reconnection. - # we only do that for client and if there is a user part, to let server - # decide for anonymous login - resource_dict = await host.memory.storage.getPrivates( - "core:xmpp", ["resource"] , profile=profile) try: - resource = resource_dict["resource"] - except KeyError: - resource = f"{C.APP_NAME_FILE}.{shortuuid.uuid()}" - await host.memory.storage.setPrivateValue( - "core:xmpp", "resource", resource, profile=profile) + port = int( + host.memory.getParamA( + C.FORCE_PORT_PARAM, "Connection", profile_key=profile + ) + ) + except ValueError: + log.debug(_("Can't parse port value, using default value")) + port = ( + None + ) # will use default value 5222 or be retrieved from a DNS SRV record - log.info(_("We'll use the stable resource {resource}").format( - resource=resource)) - entity_jid.resource = resource - - if profile in host.profiles: - raise exceptions.InternalError( - f"There is already a profile of name {profile} in host") - entity = host.profiles[profile] = cls( - host, profile, entity_jid, password, - host.memory.getParamA(C.FORCE_SERVER_PARAM, "Connection", - profile_key=profile) or None, - port, max_retries, + password = await host.memory.asyncGetParamA( + "Password", "Connection", profile_key=profile ) - await entity.encryption.loadSessions() + entity_jid_s = await host.memory.asyncGetParamA( + "JabberID", "Connection", profile_key=profile) + entity_jid = jid.JID(entity_jid_s) - entity._createSubProtocols() + if not entity_jid.resource and not cls.is_component and entity_jid.user: + # if no resource is specified, we create our own instead of using + # server returned one, as it will then stay stable in case of + # reconnection. we only do that for client and if there is a user part, to + # let server decide for anonymous login + resource_dict = await host.memory.storage.getPrivates( + "core:xmpp", ["resource"] , profile=profile) + try: + resource = resource_dict["resource"] + except KeyError: + resource = f"{C.APP_NAME_FILE}.{shortuuid.uuid()}" + await host.memory.storage.setPrivateValue( + "core:xmpp", "resource", resource, profile=profile) - entity.fallBack = SatFallbackHandler(host) - entity.fallBack.setHandlerParent(entity) + log.info(_("We'll use the stable resource {resource}").format( + resource=resource)) + entity_jid.resource = resource - entity.versionHandler = SatVersionHandler(C.APP_NAME_FULL, host.full_version) - entity.versionHandler.setHandlerParent(entity) + if profile in host.profiles: + if host.profiles[profile].isConnected(): + raise exceptions.InternalError( + f"There is already a connected profile of name {profile!r} in " + f"host") + log.debug( + "removing unconnected profile {profile!r}") + del host.profiles[profile] + entity = host.profiles[profile] = cls( + host, profile, entity_jid, password, + host.memory.getParamA(C.FORCE_SERVER_PARAM, "Connection", + profile_key=profile) or None, + port, max_retries, + ) - entity.identityHandler = SatIdentityHandler() - entity.identityHandler.setHandlerParent(entity) + await entity.encryption.loadSessions() - log.debug(_("setting plugins parents")) + entity._createSubProtocols() - plugin_conn_cb = await entity._callConnectionTriggers() + entity.fallBack = SatFallbackHandler(host) + entity.fallBack.setHandlerParent(entity) - entity.startService() + entity.versionHandler = SatVersionHandler(C.APP_NAME_FULL, host.full_version) + entity.versionHandler.setHandlerParent(entity) - await entity.conn_deferred + entity.identityHandler = SatIdentityHandler() + entity.identityHandler.setHandlerParent(entity) - await defer.maybeDeferred(entity.entityConnected) + log.debug(_("setting plugins parents")) - # Call profileConnected callback for all plugins, - # and print error message if any of them fails - conn_cb_list = [] - for __, callback in plugin_conn_cb: - conn_cb_list.append(utils.asDeferred(callback, entity)) - list_d = defer.DeferredList(conn_cb_list) + plugin_conn_cb = await entity._callConnectionTriggers() - def logPluginResults(results): - all_succeed = all([success for success, result in results]) - if not all_succeed: - log.error(_("Plugins initialisation error")) - for idx, (success, result) in enumerate(results): - if not success: - log.error( - "error (plugin %(name)s): %(failure)s" - % { - "name": plugin_conn_cb[idx][0]._info["import_name"], - "failure": result, - } - ) + entity.startService() - await list_d.addCallback( - logPluginResults - ) # FIXME: we should have a timeout here, and a way to know if a plugin freeze - # TODO: mesure launch time of each plugin + await entity.conn_deferred - cls.profiles_connecting.remove(profile) + await defer.maybeDeferred(entity.entityConnected) + + # Call profileConnected callback for all plugins, + # and print error message if any of them fails + conn_cb_list = [] + for __, callback in plugin_conn_cb: + conn_cb_list.append(utils.asDeferred(callback, entity)) + list_d = defer.DeferredList(conn_cb_list) + + def logPluginResults(results): + all_succeed = all([success for success, result in results]) + if not all_succeed: + log.error(_("Plugins initialisation error")) + for idx, (success, result) in enumerate(results): + if not success: + log.error( + "error (plugin %(name)s): %(failure)s" + % { + "name": plugin_conn_cb[idx][0]._info["import_name"], + "failure": result, + } + ) + + await list_d.addCallback( + logPluginResults + ) # FIXME: we should have a timeout here, and a way to know if a plugin freeze + # TODO: mesure launch time of each plugin + finally: + cls.profiles_connecting.remove(profile) def _disconnectionCb(self, __): self._connected_d = None