diff --git a/CHANGES/3406.feature b/CHANGES/3406.feature new file mode 100644 index 00000000000..c6ce99a386a --- /dev/null +++ b/CHANGES/3406.feature @@ -0,0 +1 @@ +Create a task per request handling. diff --git a/aiohttp/web_protocol.py b/aiohttp/web_protocol.py index a47919f6738..0919f86277d 100644 --- a/aiohttp/web_protocol.py +++ b/aiohttp/web_protocol.py @@ -400,7 +400,10 @@ async def start(self) -> None: message, payload, self, writer, handler) try: try: - resp = await self._request_handler(request) + # a new task is used for copy context vars (#3406) + task = self._loop.create_task( + self._request_handler(request)) + resp = await task except HTTPException as exc: resp = exc except asyncio.CancelledError: diff --git a/tests/test_web_protocol.py b/tests/test_web_protocol.py index caaf91b7934..829d1ec4fae 100644 --- a/tests/test_web_protocol.py +++ b/tests/test_web_protocol.py @@ -237,7 +237,7 @@ async def test_simple(srv, buf) -> None: srv.data_received( b'GET / HTTP/1.1\r\n\r\n') - await asyncio.sleep(0) + await asyncio.sleep(0.05) assert buf.startswith(b'HTTP/1.1 200 OK\r\n') @@ -450,7 +450,7 @@ async def handle_request(request): b'Content-Length: 50\r\n\r\n') await asyncio.sleep(0) assert not transport.close.called - await asyncio.sleep(0) + await asyncio.sleep(0.05) transport.close.assert_called_with() @@ -465,7 +465,7 @@ async def handle_request(request): srv.connection_made(transport) request_handler.side_effect = handle_request - await asyncio.sleep(0) + await asyncio.sleep(0.05) assert not transport.close.called srv.data_received( @@ -475,7 +475,7 @@ async def handle_request(request): await asyncio.sleep(0) assert not transport.close.called - await asyncio.sleep(0) + await asyncio.sleep(0.05) transport.close.assert_called_with() @@ -490,7 +490,7 @@ async def test_handle_payload_access_error( b'some data' ) # start request_handler task - await asyncio.sleep(0) + await asyncio.sleep(0.05) with pytest.raises(web.PayloadAccessError): await request_handler.call_args[0][0].content.read() @@ -582,9 +582,10 @@ async def test_keep_alive(make_srv, transport, ceil) -> None: b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0) - waiter = srv._waiter - assert waiter + waiter = None + while waiter is None: + await asyncio.sleep(0) + waiter = srv._waiter assert srv._keepalive_handle is not None assert not transport.close.called @@ -681,7 +682,7 @@ async def test_close(srv, transport) -> None: b'Host: example.com\r\n' b'Content-Length: 0\r\n\r\n') - await asyncio.sleep(0) + await asyncio.sleep(0.05) assert srv._task_handler assert srv._waiter @@ -721,7 +722,7 @@ async def handle(request): assert len(srv._messages) == 2 assert srv._waiter is not None - await asyncio.sleep(0) + await asyncio.sleep(0.05) assert srv._task_handler is not None assert srv._waiter is not None assert processed == 2 @@ -856,3 +857,4 @@ async def test_two_data_received_without_waking_up_start_task(srv) -> None: assert len(srv._messages) == 2 assert srv._waiter.done() + await asyncio.sleep(0.01)