Issue30083
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2017-04-16 18:18 by socketpair, last changed 2022-04-11 14:58 by admin.
Messages (2) | |||
---|---|---|---|
msg291763 - (view) | Author: Марк Коренберг (socketpair) * | Date: 2017-04-16 18:18 | |
How to reproduce: Run the following program: ========================= import asyncio async def handle_connection(reader, writer): try: await reader.readexactly(42) except BaseException as err: print('Interesting: %r.' % err) raise finally: writer.close() loop = asyncio.get_event_loop() coro = asyncio.start_server(handle_connection, '127.0.0.1', 8888) server = loop.run_until_complete(coro) try: loop.run_forever() except KeyboardInterrupt: print('KeyboardInterrupt catched.') server.close() loop.run_until_complete(server.wait_closed()) loop.close() ========================= 0. Python 3.5.2 1. Connect using telnet to localhost and port 888, type one short line and press Enter. 2. Type Ctrl+C in terminal where programw is running. 3. You will see the following output: ========================= ^CKeyboardInterrupt catched. Interesting: GeneratorExit(). Exception ignored in: <coroutine object handle_connection at 0x7fa6a1d91b48> Traceback (most recent call last): File "bug.py", line 12, in handle_connection writer.close() File "/usr/lib/python3.5/asyncio/streams.py", line 306, in close return self._transport.close() File "/usr/lib/python3.5/asyncio/selector_events.py", line 591, in close self._loop.call_soon(self._call_connection_lost, None) File "/usr/lib/python3.5/asyncio/base_events.py", line 567, in call_soon handle = self._call_soon(callback, args) File "/usr/lib/python3.5/asyncio/base_events.py", line 576, in _call_soon self._check_closed() File "/usr/lib/python3.5/asyncio/base_events.py", line 356, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<handle_connection() done, defined at bug.py:4> wait_for=<Future pending cb=[Task._wakeup()]>> ========================= This is almost canonical example of asyncio usage. So I have two questions: 1. Why coroutine is interrupted with GeneratorExit instead of CancelledError ? 2. Why something happend AFTER io loop is closed ? 3. How to code all that right ? I want to close connection on any error. Example provided is simplified code. In real code it looks like: ===== try: await asyncio.wait_for(self._handle_connection(reader, writer), 60) except asyncio.TimeoutError: writer.transport.abort() except asyncio.CancelledError: writer.transport.abort() except Exception: writer.transport.abort() finally: writer.close() ===== |
|||
msg377104 - (view) | Author: Guilherme Salgado (salgado) * | Date: 2020-09-18 10:56 | |
I've also been affected by this and found that if you use asyncio.run() the coroutine is interrupted with a CancelledError as you'd expect. The following script shows that ======================= import asyncio async def handle_connection(reader, writer): try: await reader.readexactly(42) except BaseException as err: print('Interesting: %r.' % err) raise finally: writer.close() async def main(): listener = await asyncio.start_server(handle_connection, '127.0.0.1', 8888) try: async with listener: await listener.serve_forever() except KeyboardInterrupt: print('KeyboardInterrupt') asyncio.run(main()) ============================================= |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:45 | admin | set | github: 74269 |
2020-09-18 10:56:44 | salgado | set | nosy:
+ salgado messages: + msg377104 |
2017-04-16 18:19:43 | socketpair | set | nosy:
+ yselivanov components: + asyncio versions: + Python 3.5 |
2017-04-16 18:18:42 | socketpair | create |