# HG changeset patch # User Goffi # Date 1396434683 -7200 # Node ID 4a8903021fda6457cb02c4df417d604834d8b3da # Parent 07b817f5a197b2dfbc8e04378b3a96d7d9b03c78 core (disco): findFeaturesSet and findServiceEntities don't use inlineCallbacks anymore, that allow a better error management (no more anonying debugger raise when discoInfo fails in debug mode) diff -r 07b817f5a197 -r 4a8903021fda src/memory/disco.py --- a/src/memory/disco.py Wed Apr 02 12:31:23 2014 +0200 +++ b/src/memory/disco.py Wed Apr 02 12:31:23 2014 +0200 @@ -21,6 +21,7 @@ from sat.core import exceptions from logging import debug, info, warning, error from twisted.words.protocols.jabber import jid +from twisted.words.protocols.jabber.error import StanzaError from twisted.internet import defer from sat.core.constants import Const as C from wokkel import disco @@ -67,8 +68,8 @@ @param profile_key: %(doc_profile_key)s @return: a Deferred which fire a boolean (True if feature is available) """ - disco_info = yield self.getInfos(jid_, profile_key) - defer.returnValue(feature in disco_info.features) + disco_infos = yield self.getInfos(jid_, profile_key) + defer.returnValue(feature in disco_infos.features) @defer.inlineCallbacks def checkFeature(self, feature, jid_=None, profile_key=C.PROF_KEY_NONE): @@ -81,12 +82,11 @@ @raise: exceptions.FeatureNotFound """ - disco_info = yield self.getInfos(jid_, profile_key) - if not feature in disco_info.features: + disco_infos = yield self.getInfos(jid_, profile_key) + if not feature in disco_infos.features: raise exceptions.FeatureNotFound - defer.returnValue(feature in disco_info) + defer.returnValue(feature in disco_infos) - @defer.inlineCallbacks def getInfos(self, jid_=None, profile_key=C.PROF_KEY_NONE): """get disco infos from jid_, filling capability hash if needed @@ -99,14 +99,18 @@ jid_ = jid.JID(client.jid.host) try: cap_hash = self.host.memory.getEntityData(jid_, [C.ENTITY_CAP_HASH], client.profile)[C.ENTITY_CAP_HASH] - disco_info = self.hashes[cap_hash] + disco_infos = self.hashes[cap_hash] + return defer.succeed(disco_infos) except KeyError: # capability hash is not available, we'll compute one - disco_info = yield client.disco.requestInfo(jid_) - cap_hash = self.generateHash(disco_info) - self.hashes[cap_hash] = disco_info - yield self.host.memory.updateEntityData(jid_, C.ENTITY_CAP_HASH, cap_hash, client.profile) - defer.returnValue(disco_info) + def infosCb(disco_infos): + cap_hash = self.generateHash(disco_infos) + self.hashes[cap_hash] = disco_infos + self.host.memory.updateEntityData(jid_, C.ENTITY_CAP_HASH, cap_hash, client.profile) + return disco_infos + d = client.disco.requestInfo(jid_) + d.addCallback(infosCb) + return d @defer.inlineCallbacks def getItems(self, jid_=None, profile_key=C.PROF_KEY_NONE): @@ -133,7 +137,11 @@ defer.returnValue(items) - @defer.inlineCallbacks + def _infosEb(self, failure, entity_jid): + failure.trap(StanzaError) + warning(_("Error while requesting [%(jid)s]: %(error)s") % {'jid': entity_jid.full(), + 'error': failure.getErrorMessage()}) + def findServiceEntities(self, category, type_, jid_=None, profile_key=C.PROF_KEY_NONE): """Return all available items of an entity which correspond to (category, type_) @@ -143,16 +151,25 @@ @param profile_key: %(doc_profile_key)s @return: a set of entities or None if no cached data were found """ - found_identities = set() - items = yield self.getItems(jid_, profile_key) - for item in items: - infos = yield self.getInfos(item.entity, profile_key) + found_entities = set() + + def infosCb(infos, entity_jid): if (category, type_) in infos.identities: - found_identities.add(item.entity) + found_entities.add(entity_jid) - defer.returnValue(found_identities) + def gotItems(items): + defers_list = [] + for item in items: + info_d = self.getInfos(item.entity, profile_key) + info_d.addCallbacks(infosCb, self._infosEb, [item.entity], None, [item.entity]) + defers_list.append(info_d) + return defer.DeferredList(defers_list) - @defer.inlineCallbacks + d = self.getItems(jid_, profile_key) + d.addCallback(gotItems) + d.addCallback(lambda dummy: found_entities) + return d + def findFeaturesSet(self, features, category=None, type_=None, jid_=None, profile_key=C.PROF_KEY_NONE): """Return entities (including jid_ and its items) offering features @@ -169,9 +186,7 @@ features = set(features) found_entities = set() - items = yield self.getItems(jid_, profile_key) - for entity in [jid_] + [item.entity for item in items]: - infos = yield self.getInfos(entity, profile_key) + def infosCb(infos, entity): if category is not None or type_ is not None: categories = set() types = set() @@ -180,13 +195,24 @@ categories.add(id_cat) types.add(id_type) if category is not None and category not in categories: - continue + return if type_ is not None and type_ not in types: - continue + return if features.issubset(infos.features): found_entities.add(entity) - defer.returnValue(found_entities) + def gotItems(items): + defer_list = [] + for entity in [jid_] + [item.entity for item in items]: + infos_d = self.getInfos(entity, profile_key) + infos_d.addCallbacks(infosCb, self._infosEb, [entity], None, [entity]) + defer_list.append(infos_d) + return defer.DeferredList(defer_list) + + d = self.getItems(jid_, profile_key) + d.addCallback(gotItems) + d.addCallback(lambda dummy: found_entities) + return d def generateHash(self, services): """ Generate a unique hash for given service