def test_subscribe_and_unsubscribe(): errors = [] Events.subscribe(UnhandledError, errors.append) Events.log(UnhandledError('actor', 1, 2)) assert errors == [UnhandledError('actor', 1, 2)] errors[:] = [] Events.unsubscribe(UnhandledError, errors.append) event = UnhandledError('actor', 1, 2) Events.log(event) assert errors == []
def test_subscribe_and_unsubscribe(): errors = [] Events.subscribe(Error, errors.append) Events.log(Error('actor', 1, 2)) assert errors == [Error('actor', 1, 2)] errors[:] = [] Events.unsubscribe(Error, errors.append) event = Error('actor', 1, 2) Events.log(event) assert errors == []
def run(self, req, responder, args, kwargs): try: self.responder = responder = self.spawn(responder.using(req, *args, **kwargs)) self.error = None try: Events.subscribe(Error, self.check_error) # XXX: it would be nicer if Events.subscribe accepted an actor ref to filter on responder.join() if not req.closed: if self.error: _send_500(req, extra='\n<pre>\n%s</pre>\n' % (''.join(traceback.format_exception(type(self.error.exc), self.error.exc, self.error.tb)),)) req.close() finally: Events.unsubscribe(Error, self.check_error) except: _send_500(req) raise
def ret(*args, **kwargs): # dbg("\n============================================\n") # TODO: once the above TODO (fresh Node for each test fn) is complete, consider making Events non-global by # having each Node have its own Events instance. Events.reset() def check_memleaks(): if '__pypy__' not in sys.builtin_module_names: gc.collect() assert not gc.garbage, "Memory leak detected: %r" % ( gc.garbage, ) # if gc.garbage: # dbg("GARGABE: detected after %s:" % (fn.__name__,), len(gc.garbage)) # import objgraph as ob # import os # def dump_chain(g_): # isframework = lambda x: type(x).__module__.startswith(spinoff.__name__) # ob.show_backrefs([g_], filename='backrefs.png', max_depth=100, highlight=isframework) # for gen in gc.garbage: # dump_chain(gen) # dbg(" TESTWRAP: mem-debuggin", gen) # import pdb; pdb.set_trace() # os.remove('backrefs.png') errors = [] Events.subscribe(Error, errors.append) try: return with_timeout( fn.timeout if hasattr(fn, 'timeout') else 0.5, fn, *args, **kwargs) finally: Events.unsubscribe(Error, errors.append) if errors: sender, exc, tb = errors[0] raise exc, None, tb del errors[:] check_memleaks()
def ret(*args, **kwargs): # dbg("\n============================================\n") # TODO: once the above TODO (fresh Node for each test fn) is complete, consider making Events non-global by # having each Node have its own Events instance. Events.reset() def check_memleaks(): if '__pypy__' not in sys.builtin_module_names: gc.collect() assert not gc.garbage, "Memory leak detected: %r" % (gc.garbage,) # if gc.garbage: # dbg("GARGABE: detected after %s:" % (fn.__name__,), len(gc.garbage)) # import objgraph as ob # import os # def dump_chain(g_): # isframework = lambda x: type(x).__module__.startswith(spinoff.__name__) # ob.show_backrefs([g_], filename='backrefs.png', max_depth=100, highlight=isframework) # for gen in gc.garbage: # dump_chain(gen) # dbg(" TESTWRAP: mem-debuggin", gen) # import pdb; pdb.set_trace() # os.remove('backrefs.png') errors = [] Events.subscribe(Error, errors.append) try: return with_timeout(fn.timeout if hasattr(fn, 'timeout') else 0.5, fn, *args, **kwargs) finally: Events.unsubscribe(Error, errors.append) if errors: sender, exc, tb = errors[0] raise exc, None, tb del errors[:] check_memleaks()
def run(self, req, responder, args, kwargs): try: self.responder = responder = self.spawn( responder.using(req, *args, **kwargs)) self.error = None try: Events.subscribe( Error, self.check_error ) # XXX: it would be nicer if Events.subscribe accepted an actor ref to filter on responder.join() if not req.closed: if self.error: _send_500(req, extra='\n<pre>\n%s</pre>\n' % (''.join( traceback.format_exception( type(self.error.exc), self.error.exc, self.error.tb)), )) req.close() finally: Events.unsubscribe(Error, self.check_error) except: _send_500(req) raise
def unsubscribe(cls): for event_type in _ERROR_EVENTS: Events.unsubscribe(event_type, ErrorCollector.collect)