remove unnecessary copies when only one handler matches. This was taking up ~ 15% of CPU on moderate load.
This commit is contained in:
parent
6f3cc77bb5
commit
48af3d3322
2 changed files with 23 additions and 18 deletions
|
@ -246,7 +246,7 @@ class BaseXMPP(XMLStream):
|
|||
spec = "(RFC-%s) " % self.plugin[plugin].rfc
|
||||
|
||||
desc = (spec, self.plugin[plugin].description)
|
||||
log.debug("Loaded Plugin %s%s" , desc)
|
||||
log.debug("Loaded Plugin %s" , desc)
|
||||
except:
|
||||
log.exception("Unable to load plugin: %s", plugin)
|
||||
|
||||
|
|
|
@ -873,20 +873,25 @@ class XMLStream(object):
|
|||
event queue. All event handlers will run in the
|
||||
same thread.
|
||||
"""
|
||||
for handler in self.__event_handlers.get(name, []):
|
||||
handlers = self.__event_handlers.get(name, [])
|
||||
for handler in handlers:
|
||||
#TODO: Data should not be copied, but should be read only,
|
||||
# but this might break current code so it's left for future.
|
||||
|
||||
out_data = copy.copy(data) if len(handlers) > 1 else data
|
||||
old_exception = getattr(data, 'exception', None)
|
||||
if direct:
|
||||
try:
|
||||
handler[0](copy.copy(data))
|
||||
handler[0](out_data)
|
||||
except Exception as e:
|
||||
error_msg = 'Error processing event handler: %s'
|
||||
log.exception(error_msg , str(handler[0]))
|
||||
if hasattr(data, 'exception'):
|
||||
data.exception(e)
|
||||
if old_exception:
|
||||
old_exception(e)
|
||||
else:
|
||||
self.exception(e)
|
||||
else:
|
||||
self.event_queue.put(('event', handler, copy.copy(data)))
|
||||
|
||||
self.event_queue.put(('event', handler, out_data))
|
||||
if handler[2]:
|
||||
# If the handler is disposable, we will go ahead and
|
||||
# remove it now instead of waiting for it to be
|
||||
|
@ -1201,17 +1206,17 @@ class XMLStream(object):
|
|||
# to run "in stream" will be executed immediately; the rest will
|
||||
# be queued.
|
||||
unhandled = True
|
||||
for handler in self.__handlers:
|
||||
if handler.match(stanza):
|
||||
stanza_copy = copy.copy(stanza)
|
||||
handler.prerun(stanza_copy)
|
||||
self.event_queue.put(('stanza', handler, stanza_copy))
|
||||
try:
|
||||
if handler.check_delete():
|
||||
self.__handlers.remove(handler)
|
||||
except:
|
||||
pass # not thread safe
|
||||
unhandled = False
|
||||
matched_handlers = filter(lambda h: h.match(stanza), self.__handlers)
|
||||
for handler in matched_handlers:
|
||||
stanza_copy = copy.copy(stanza) if len(matched_handlers) > 1 else stanza
|
||||
handler.prerun(stanza_copy)
|
||||
self.event_queue.put(('stanza', handler, stanza_copy))
|
||||
try:
|
||||
if handler.check_delete():
|
||||
self.__handlers.remove(handler)
|
||||
except:
|
||||
pass # not thread safe
|
||||
unhandled = False
|
||||
|
||||
# Some stanzas require responses, such as Iq queries. A default
|
||||
# handler will be executed immediately for this case.
|
||||
|
|
Loading…
Reference in a new issue