def test_callbacks(self): data = [] def callback2(): data.append(2) def finish_callback(): self.assertEqual(data, [1, 2]) data.append(3) ag = AsyncGroup(finish_callback) cb1 = ag.add(partial(data.append, 1)) cb2 = ag.add(callback2) self.assertEqual(ag._finish_cb_called, False) ag.try_finish() self.assertEqual(ag._finish_cb_called, False) cb1() self.assertEqual(ag._finish_cb_called, False) cb2() self.assertEqual(ag._finish_cb_called, True) self.assertEqual(ag._aborted, False) self.assertEqual(data, [1, 2, 3])
def test_exception_in_first(self): def callback1(): raise Exception('callback1 error') def callback2(): self.fail('callback2 should not be called') def finish_callback(): self.fail('finish_callback should not be called') ag = AsyncGroup(finish_callback, name='test_group') cb1 = ag.add(callback1) cb2 = ag.add(callback2) self.assertRaises(Exception, cb1) self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True) with ExpectLog( async_logger, '.*test_group group: ignoring response because of already finished group' ): cb2() self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True)
def test_exception_in_first(self): log = [] def callback1(): raise Exception('callback1 error') def callback2(): self.fail('callback2 should not be called') def finish_callback(): self.fail('finish_callback should not be called') ag = AsyncGroup(finish_callback, log=lambda msg, *args: log.append(msg % args), name='test_group') cb1 = ag.add(callback1) cb2 = ag.add(callback2) self.assertRaises(Exception, cb1) self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True) cb2() self.assertEqual(log[-1], 'test_group group: Ignoring response because of already finished group') self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True)
def test_exception_in_first(self): log = [] def callback1(): raise Exception('callback1 error') def callback2(): self.fail('callback2 should not be called') def finish_callback(): self.fail('finish_callback should not be called') ag = AsyncGroup(finish_callback, log=lambda msg, *args: log.append(msg % args), name='test_group') cb1 = ag.add(callback1) cb2 = ag.add(callback2) self.assertRaises(Exception, cb1) self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True) cb2() self.assertEqual(log[-1], 'test_group group: ignoring response because of already finished group') self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True)
def group(self, futures, callback=None, name=None): if callable(callback): results_holder = {} group_callback = self.handler.finish_group.add( partial(callback, results_holder)) def delay_cb(): IOLoop.instance().add_callback( self.handler.check_finished(group_callback)) async_group = AsyncGroup(delay_cb, logger=self.handler.log, name=name) def future_callback(name, future): results_holder[name] = future.result() for name, future in iteritems(futures): if future.done(): future_callback(name, future) else: self.handler.add_future( future, async_group.add(partial(future_callback, name))) async_group.try_finish() return futures
def get_page(self): def finished(): res = etree.Element('result') res.text = str(self.result) self.doc.put(res) self.set_header('X-Foo', 'Bar') self.set_status(400) self.result = 0 ag = AsyncGroup(finished) def accumulate(xml, response): if response.code >= 400: raise HTTPError(503, 'remote server returned error with code {}'.format(response.code)) if xml is None: raise HTTPError(503) self.result += int(xml.findtext('a')) self.get_url(self.config.serviceHost + 'vacancy/1234', callback=ag.add(accumulate)) self.get_url(self.config.serviceHost + 'employer/1234', callback=ag.add(accumulate))
def test_exception_in_last(self): log = [] def callback2(): raise Exception('callback1 error') def finish_callback(): self.fail('finish_callback should not be called') ag = AsyncGroup(finish_callback, log=lambda msg, *args: log.append(msg % args), name='test_group') cb1 = ag.add(lambda: None) cb2 = ag.add(callback2) cb1() self.assertRaises(Exception, cb2) self.assertEqual(log[-2], 'test_group group: aborting async group due to unhandled exception in callback') self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True)
def _function_under_test(handler): def finished(): res = lxml.etree.Element('result') res.text = str(handler.result) handler.doc.put(res) handler.set_header('X-Foo', 'Bar') handler.set_status(400) handler.result = 0 ag = AsyncGroup(finished) def accumulate(xml, response): if response.code >= 400: raise HTTPError(503, 'remote server returned error with code {}'.format(response.code)) if xml is None: raise HTTPError(503) handler.result += int(xml.findtext('a')) handler.get_url(handler.config.serviceHost + 'vacancy/1234', callback=ag.add(accumulate)) handler.get_url(handler.config.serviceHost + 'employer/1234', callback=ag.add(accumulate))
def _function_under_test(handler): def finished(): res = lxml.etree.Element("result") res.text = str(handler.result) handler.doc.put(res) handler.set_header('X-Foo', 'Bar') handler.set_status(400) handler.result = 0 ag = AsyncGroup(finished) def accumulate(xml, response): if response.code >= 400: raise HTTPError(503, "remote server returned error with code =" + str(response.code)) if xml is None: raise HTTPError(503) handler.result += int(xml.findtext("a")) handler.get_url(handler.config.serviceHost + 'vacancy/1234', callback=ag.add(accumulate)) handler.get_url(handler.config.serviceHost + 'employer/1234', callback=ag.add(accumulate))
def test_exception_in_last(self): def callback2(): raise Exception('callback1 error') def finish_callback(): self.fail('finish_callback should not be called') ag = AsyncGroup(finish_callback, name='test_group') cb1 = ag.add(lambda: None) cb2 = ag.add(callback2) cb1() with ExpectLog( async_logger, '.*test_group group: aborting async group due to unhandled exception in callback' ): self.assertRaises(Exception, cb2) self.assertEqual(ag._finish_cb_called, False) self.assertEqual(ag._aborted, True)
def get_page(self): n = int(self.get_argument('n')) self_uri = self.request.host + self.request.path self.add_header('Content-Type', 'text/plain') if n < 2: self.text = '1' return self.acc = 0 def intermediate_cb(text, response): self.acc += int(text) def final_cb(): self.text = str(self.acc) grp = AsyncGroup(final_cb, name='acc') self.get_url(self_uri, {'n': str(n - 1)}, callback=grp.add(intermediate_cb)) self.get_url(self_uri, {'n': str(n - 2)}, callback=grp.add(intermediate_cb))
def get_page(self): def finished(): res = lxml.etree.Element('result') res.text = str(self.result) self.doc.put(res) self.set_header('X-Foo', 'Bar') self.set_status(400) self.result = 0 ag = AsyncGroup(finished) def accumulate(xml, response): if response.code >= 400: raise HTTPError( 503, 'remote server returned error with code {}'.format( response.code)) if xml is None: raise HTTPError(503) self.result += int(xml.findtext('a')) self.get_url(self.config.serviceHost + 'vacancy/1234', callback=ag.add(accumulate)) self.get_url(self.config.serviceHost + 'employer/1234', callback=ag.add(accumulate))
def group(self, futures, callback=None, name=None): if callable(callback): results_holder = {} group_callback = self.handler.finish_group.add(partial(callback, results_holder)) def delay_cb(): IOLoop.instance().add_callback(self.handler.check_finished(group_callback)) async_group = AsyncGroup(delay_cb, logger=self.handler.log, name=name) def callback(future_name, future): results_holder[future_name] = future.result() for name, future in futures.iteritems(): future.add_done_callback(async_group.add(partial(callback, name))) async_group.try_finish() return futures
def group(self, futures, callback=None, name=None): if callable(callback): results_holder = {} group_callback = self.handler.finish_group.add( self.handler.check_finished(callback, results_holder)) async_group = AsyncGroup(group_callback, name=name) def future_callback(name, future): results_holder[name] = future.result() for name, future in iteritems(futures): if future.done(): future_callback(name, future) else: self.handler.add_future( future, async_group.add(partial(future_callback, name))) async_group.try_finish_async() return futures
def group(self, futures, callback=None, name=None): if callable(callback): results_holder = {} group_callback = self.handler.finish_group.add( partial(callback, results_holder)) def delay_cb(): IOLoop.instance().add_callback( self.handler.check_finished(group_callback)) async_group = AsyncGroup(delay_cb, log=self.handler.log.debug, name=name) def callback(future_name, future): results_holder[future_name] = future.result().get() for name, future in futures.iteritems(): future.add_done_callback( async_group.add(partial(callback, name))) async_group.try_finish() return futures