def test_linger_on(self): quit_handler = locks.Event() handler_completed = locks.Event() async def handler(request, response): del request response.headers['Content-Type'] = 'text/plain' await response.write(b'hello world') response.close() await quit_handler.wait() handler_completed.set() async def get_content(content_iterator): content = [] async for data in content_iterator: content.append(data) if not content: return None else: return b''.join(content) app = wsgi_apps.Application(handler) app_task = tasks.spawn(app(self.ENVIRON, self.start_response_mock)) with self.assertRaises(kernels.KernelTimeout): kernels.run(timeout=0.01) self.assertTrue(app_task.is_completed()) self.assertFalse(handler_completed.is_set()) self.start_response_mock.assert_called_once_with( '200 OK', [('Content-Type', 'text/plain')], ) self.assertEqual( kernels.run( get_content(app_task.get_result_nonblocking()), timeout=0.01, ), b'hello world', ) # Handler lingers on after application completes. self.assertFalse(handler_completed.is_set()) quit_handler.set() kernels.run(timeout=0.01) self.assertTrue(handler_completed.is_set()) app.shutdown() kernels.run(app.serve(), timeout=0.01)
def test_get_nonblocking(self): tq = tasks.CompletionQueue() with self.assertRaises(tasks.Empty): tq.get_nonblocking() gettable_task = self.k.spawn(tq.gettable()) with self.assertRaises(errors.KernelTimeout): self.k.run(timeout=0.01) self.assertFalse(gettable_task.is_completed()) event = locks.Event() t1 = self.k.spawn(event.wait) t2 = self.k.spawn(event.wait) tq.put_nonblocking(t1) tq.put_nonblocking(t2) tq.close() with self.assertRaises(errors.KernelTimeout): self.k.run(timeout=0.01) with self.assertRaises(tasks.Empty): tq.get_nonblocking() event.set() self.k.run(timeout=0.01) self.assertTrue(gettable_task.is_completed()) self.assertCountEqual( [tq.get_nonblocking(), tq.get_nonblocking()], [t1, t2], ) with self.assertRaises(tasks.Closed): tq.get_nonblocking() self.k.run(tq.gettable())
def test_event(self): e = locks.Event() self.assertFalse(e.is_set()) e.set() self.assertTrue(e.is_set()) e.set() # You may call it repeatedly. self.assertTrue(e.is_set()) e.clear() self.assertFalse(e.is_set()) e.clear() # You may call it repeatedly. self.assertFalse(e.is_set()) e.set() self.assertTrue(self.k.run(e.wait, timeout=1)) self.assertEqual(self.k.get_stats().num_blocked, 0) self.assertEqual(len(self.k._generic_blocker), 0) e.clear() with self.assertRaises(errors.KernelTimeout): self.k.run(e.wait, timeout=0) self.assertEqual(self.k.get_stats().num_blocked, 1) self.assertEqual(len(self.k._generic_blocker), 1) e.set() self.assertTrue(self.k.run(e.wait, timeout=1)) self.assertEqual(self.k.get_stats().num_blocked, 0) self.assertEqual(len(self.k._generic_blocker), 0)
def test_context_manager_cancel(self): tq = tasks.CompletionQueue() event = locks.Event() t1 = self.k.spawn(event.wait) tq.put_nonblocking(t1) t2 = self.k.spawn(event.wait) tq.put_nonblocking(t2) t3 = self.k.spawn(raises('test message')) tq.put_nonblocking(t3) async def do_with_queue(): async with tq: raise Exception('some error') with self.assertRaisesRegex(Exception, r'some error'): self.k.run(do_with_queue) self.assertTrue(tq.is_closed()) self.assertFalse(tq) self.assertEqual(len(tq), 0) for t in (t1, t2): self.assertTrue(t.is_completed()) with self.assertRaises(errors.Cancelled): t.get_result_nonblocking() self.assertTrue(t3.is_completed()) with self.assertRaisesRegex(Exception, r'test message'): t3.get_result_nonblocking()
def test_always_cancel(self): async def test_cancel(t): async with tasks.joining(t, always_cancel=True): pass t = self.k.spawn(locks.Event().wait) self.k.run(test_cancel(t)) self.assertTrue(t.is_completed()) with self.assertRaises(errors.Cancelled): t.get_result_nonblocking()
def setUp(self): super().setUp() self.main_task = None self.agent_queue = tasks.CompletionQueue() self.graceful_exit = locks.Event() self.signal_queue = queues.Queue() mock = unittest.mock.patch(agents.__name__ + '.signals').start() mock.SignalSource().__enter__().get = self.signal_queue.get self._assert_logs = self.assertLogs(agents.__name__, level='DEBUG') self.cm = self._assert_logs.__enter__()
def test_handler_error(self): event = locks.Event() server_task = self.queue.spawn(event.wait) self.queue.spawn(raises(ValueError('some error'))) self.assert_state(False, 2, []) with self.assertRaises(kernels.KernelTimeout): self.run_supervisor([server_task]) self.assert_state(False, 1, [r'handler task error: ']) event.set() self.assertIsNone(kernels.run(timeout=1)) self.assert_state(True, 0, [r'handler task error: ', r'server task exit: ']) self.assertTrue(server_task.get_result_nonblocking()) self.assertFalse(tasks.get_all_tasks(), [])
def test_event(self): with self.assertRaises(LookupError): contexts.get_kernel() e = locks.Event() self.assertFalse(e.is_set()) e.set() self.assertTrue(e.is_set()) e.set() # You may call it repeatedly. self.assertTrue(e.is_set()) e.clear() self.assertFalse(e.is_set()) e.clear() # You may call it repeatedly. self.assertFalse(e.is_set())
def __init__(self, start_response, is_sendfile_supported): self._start_response = start_response self._status = consts.Statuses.OK self.headers = self.Headers(self.is_uncommitted) self._precommit = self._make_precommit() # Set capacity to 1 to prevent excessive buffering. self._body = queues.Queue(capacity=1) self.file = None self._send_mechanism = _SendMechanisms.UNDECIDED self._send_mechanism_decided = locks.Event() if not is_sendfile_supported: self._set_send_mechanism(_SendMechanisms.SEND)
def test_joining(self): async def test_normal(t1): async with tasks.joining(t1) as t2: self.assertIs(t1, t2) async def test_error(t1): async with tasks.joining(t1) as t2: self.assertIs(t1, t2) raise Exception('some error') t = self.k.spawn(square(2)) self.k.run(test_normal(t)) self.assertTrue(t.is_completed()) self.assertEqual(t.get_result_nonblocking(), 4) t = self.k.spawn(locks.Event().wait) with self.assertRaisesRegex(Exception, r'some error'): self.k.run(test_error(t)) self.assertTrue(t.is_completed()) with self.assertRaises(errors.Cancelled): t.get_result_nonblocking()
def do_test_headers_sent_blocking(self, make_coro): def assert_begin_but_not_sent(): self.assertEqual(self.response_queue.has_begun(), True) self.assertEqual(self.response_queue._has_begun, True) self.assertEqual(self.response_queue._headers_sent.is_set(), False) block_send = locks.Event() async def mock_send(data): del data # Unused. await block_send.wait() return 1 self.mock_sock.send.side_effect = mock_send self.mock_sock.sendfile.side_effect = mock_send begin_task = tasks.spawn( self.response_queue.begin(http.HTTPStatus.OK, [])) with self.assertRaises(kernels.KernelTimeout): kernels.run(timeout=0.01) assert_begin_but_not_sent() self.assertFalse(begin_task.is_completed()) send_task = tasks.spawn(make_coro()) with self.assertRaises(kernels.KernelTimeout): kernels.run(timeout=0.01) assert_begin_but_not_sent() self.assertFalse(begin_task.is_completed()) self.assertFalse(send_task.is_completed()) block_send.set() kernels.run(timeout=0.01) self.assert_begin(True) self.assertTrue(begin_task.is_completed()) self.assertTrue(send_task.is_completed()) begin_task.get_result_nonblocking() send_task.get_result_nonblocking()
async def run(self, handle): event = locks.Event() kernel = ASSERT.not_none(kernels.get_kernel()) callback = _nng.nng_aio_callback( lambda _: kernel.post_callback(event.set)) aio_p = _nng.nng_aio_p() errors.check(_nng.F.nng_aio_alloc(ctypes.byref(aio_p), callback, None)) try: # Strangely, the default is not ``NNG_DURATION_DEFAULT`` but # ``NNG_DURATION_INFINITE``; let's make default the default. _nng.F.nng_aio_set_timeout(aio_p, _nng.NNG_DURATION_DEFAULT) self.transceive(handle, aio_p) try: await event.wait() except BaseException: _nng.F.nng_aio_cancel(aio_p) raise errors.check(_nng.F.nng_aio_result(aio_p)) return self.make_result(aio_p) finally: # Call ``nng_aio_wait`` to ensure that AIO is completed and # we may safely read its result or free it (in case we are # here due to an exception). _nng.F.nng_aio_wait(aio_p) self.cleanup(aio_p) _nng.F.nng_aio_free(aio_p)
def test_put_and_capacity(self): tq = tasks.CompletionQueue(capacity=1) self.assertFalse(tq.is_full()) event = locks.Event() t1 = self.k.spawn(event.wait) t2 = self.k.spawn(square(2)) tq.put_nonblocking(t1) self.assertTrue(tq.is_full()) with self.assertRaises(tasks.Full): tq.put_nonblocking(t2) puttable_task = self.k.spawn(tq.puttable()) with self.assertRaises(errors.KernelTimeout): self.k.run(timeout=0.01) self.assertFalse(puttable_task.is_completed()) self.assertTrue(tq.is_full()) event.set() self.k.run(timeout=0.01) self.assertFalse(tq.is_full()) self.assertTrue(puttable_task.is_completed()) tq.close() self.k.run(tq.puttable())
'agent_queue', 'graceful_exit', 'grace_period', # shutdown_agents. 'shutdown_queue', ) PARAMS = parameters.define( agents.__name__, parameters.Namespace(grace_period=parameters.Parameter(4, type=(int, float), unit='seconds'), ), ) startup.set(LABELS.agent_queue, tasks.CompletionQueue()) startup.set(LABELS.graceful_exit, locks.Event()) startup.set(LABELS.shutdown_queue, queues.Queue()) utils.depend_parameter_for(LABELS.grace_period, PARAMS.grace_period) utils.define_binder( agents.supervise_agents, LABELS.supervise_agents, { 'agent_queue': LABELS.agent_queue, 'graceful_exit': LABELS.graceful_exit, 'grace_period': LABELS.grace_period, }, )
def __init__(self, sock): self._sock = sock self._has_begun = False self._headers_sent = locks.Event() self._send_mechanism = _SendMechanisms.UNDECIDED