Reputation: 51
I have a program that needs to run multiple independent tasks. I need a way to start them and then stop them when an event occur
I've defined a base class like this
class InterruptibleTask:
def __init__(self, stop_evt=None):
self.stop_evt = stop_evt or asyncio.Event()
async def init(self):
pass
async def cleanup(self):
pass
async def run(self):
await self.init()
await self.stop_evt.wait()
await self.cleanup()
async def stop(self):
self.stop_evt.set()
class MyFirstTask(InterruptibleTask):
async def do_work(self):
while not self.stop_evt.is_set:
print("Do Work")
asyncio.sleep(1)
async def init(self):
await asyncio.create_task(self.do_work())
class MysecondTask(InterruptibleTask):
async def do_work(self):
while not self.stop_evt.is_set:
print("Do 2nd Work")
asyncio.sleep(3)
async def init(self):
await asyncio.create_task(self.do_work())
STOP = asyncio.Event()
tasks = [MyFirstTask(STOP), MysecondTask(STOP)]
async def run_tasks():
await asyncio.gather(*tasks)
def stop_tasks():
for task in tasks:
task.stop()
try
asyncio.run(run_tasks())
except KeyboardInterrupt:
pass
finally:
stop_tasks()
It this the right approach? Do you have any example? How can I stop all taks and subtask on exit?
Upvotes: 0
Views: 390
Reputation: 338
What I do when I have several coroutines and want to stop my loop:
try:
loop.run_until_complete(main())
except KeyboardInterrupt:
pending = asyncio.Task.all_tasks()
for c in pending:
asyncio.wait_for(c, timeout=5)
finally:
loop.stop()
So I don't have to have any bookkeeping of my coroutines and can still make sure that every coroutine is stopped. And since there can be coroutines that can take quite a long time to finish I add a timeout, so I don't have to wait for years for my programm to shut down.
Upvotes: 1