I'm trying 2 ways to stop an infinite loop from running:
- supervisor_1: task is canceled programatically
- supervisor_2: task is stopped with Ctrl+C
While supervisor_2 does not throw any errors at when interrupted, I cannot get supervisor_1 from getting Task was destroyed but it is pending!. Any idea why ?
Here is the code:
import asyncio
import aioredis
from functools import partial
class Listener:
    def __init__(self, redis_conn):
        self.redis_conn = redis_conn
    async def forever(self, loop_name):
        counter = 0
        try:
            while True:
                print('{}: {}'.format(loop_name, counter))
                counter += 1
                await asyncio.sleep(1)
        except asyncio.CancelledError:
            print('Task Cancelled')
            self.redis_conn.close()
            await self.redis_conn.wait_closed()
async def supervisor_1(redis_conn):
    redis_conn = await redis_conn
    l = Listener(redis_conn)
    task = asyncio.ensure_future(
        asyncio.gather(l.forever('loop_1'), 
                       l.forever('loop_2')))
    await asyncio.sleep(2)
    task.cancel()
async def supervisor_2(redis_conn):
    redis_conn = await redis_conn
    l = Listener(redis_conn)
    await asyncio.gather(l.forever('loop_1'), 
                         l.forever('loop_2'))
if __name__ == '__main__':
    redis_conn = aioredis.create_pool(('localhost', 5003), db=1)
    loop = asyncio.get_event_loop()
    run = partial(supervisor_2, redis_conn=redis_conn)
    task = asyncio.ensure_future(run())
    try:
        loop.run_until_complete(task)
    except KeyboardInterrupt:
        print('Interruped !')
        task.cancel()
        loop.run_forever()
    finally:
        loop.close()
@update:
Thanks to @Gerasimov, here is a version that fix the problem, but somehow still raise errors from time to time on KeyboardInterrupt:
async def supervisor(redis_conn):
    redis_conn = await redis_conn
    l = Listener(redis_conn)
    task = asyncio.ensure_future(
        asyncio.gather(l.forever('loop_1'), 
                       l.forever('loop_2'))
    )
    await asyncio.sleep(10)
    task.cancel()
    with suppress(asyncio.CancelledError):
        await task
async def kill_tasks():
    pending = asyncio.Task.all_tasks()
    for task in pending:
        task.cancel()
        with suppress(asyncio.CancelledError):
            await task 
and
if __name__ == '__main__':
    redis_conn = aioredis.create_pool(('localhost', 5003), db=1)
    loop = asyncio.get_event_loop()
    run = partial(supervisor, redis_conn=redis_conn)
    task = asyncio.ensure_future(run())
    try:
        loop.run_until_complete(task)
    except KeyboardInterrupt:
        print('Interruped !')
        loop.run_until_complete(kill_tasks())
    finally:
        loop.close()
 
     
    