# HG changeset patch # User Goffi # Date 1547232286 -3600 # Node ID a97c43dc492428ef2d060b79089a94a6713afb2b # Parent 93a421de0e3d9c5e37eef949cc8dc3d28f7a189b core: findByFeatures speed improvments: - DeferredList are used instead of waiting for each disco individually - a Timeout of 10 s is set for jids, to avoid waiting for minutes when some entity is unreachable (which leads to terrible user experience while waiting for a discovery page) diff -r 93a421de0e3d -r a97c43dc4924 sat/core/sat_main.py --- a/sat/core/sat_main.py Fri Jan 11 16:35:13 2019 +0100 +++ b/sat/core/sat_main.py Fri Jan 11 19:44:46 2019 +0100 @@ -872,11 +872,19 @@ found_roster = {} if service: services_jids = yield self.findFeaturesSet(client, namespaces) - for service_jid in services_jids: - infos = yield self.getDiscoInfos(client, service_jid) - if identities is not None and not set(infos.identities.keys()).issuperset( - identities - ): + services_infos = yield defer.DeferredList( + [self.getDiscoInfos(client, service_jid) for service_jid in services_jids] + ) + + for idx, (success, infos) in enumerate(services_infos): + service_jid = services_jids[idx] + if not success: + log.warning( + _(u"Can't find features for service {service_jid}, ignoring") + .format(service_jid=service_jid.full())) + continue + if (identities is not None + and not set(infos.identities.keys()).issuperset(identities)): continue found_identities = [ (cat, type_, name or u"") @@ -890,6 +898,9 @@ if roster: to_find.append((found_roster, client.roster.getJids())) + full_jids = [] + d_list = [] + for found, jids in to_find: for jid_ in jids: if jid_.resource: @@ -913,17 +924,34 @@ full_jid = jid.JID(tuple=(jid_.user, jid_.host, resource)) if full_jid == client.jid and not local_device: continue - infos = yield self.getDiscoInfos(client, full_jid) - if infos.features.issuperset(namespaces): - if identities is not None and not set( - infos.identities.keys() - ).issuperset(identities): - continue - found_identities = [ - (cat, type_, name or u"") - for (cat, type_), name in infos.identities.iteritems() - ] - found[full_jid.full()] = found_identities + full_jids.append(full_jid) + + d_list.append(self.getDiscoInfos(client, full_jid)) + + d_list = defer.DeferredList(d_list) + # XXX: 10 seconds may be too low for slow connections (e.g. mobiles) + # but for discovery, that's also the time the user will wait the first time + # before seing the page. + d_list.addTimeout(10, reactor) + infos_data = yield d_list + + for idx, (success, infos) in enumerate(infos_data): + full_jid = full_jids[idx] + if not success: + log.warning( + _(u"Can't retrieve {full_jid} infos, ignoring") + .format(full_jid=full_jid.full())) + continue + if infos.features.issuperset(namespaces): + if identities is not None and not set( + infos.identities.keys() + ).issuperset(identities): + continue + found_identities = [ + (cat, type_, name or u"") + for (cat, type_), name in infos.identities.iteritems() + ] + found[full_jid.full()] = found_identities defer.returnValue((found_service, found_own, found_roster))