Reputation: 888
I have a parent function which should run 2 tests on a data set.
if any of these tests fail parent function should return fail. I want to run these 2 tests asynchronously with asyncio and as soon as one of the tests failed, parent function should return fail and cancel the other test.
I'm new to asyncio and read some examples with the condition here but couldn't figure out how to write asyncio with conditions.
so far I could handle it by throwing exceptions in any test that has been failed.
here is my basic code:
async def test1(data):
# run some test on data and return true on pass and throw exception on fail
async def test2(data):
# run some test on data and return true on pass and throw exception on fail
ioloop = asyncio.get_event_loop()
tasks = [ioloop.create_task(test1(data)), ioloop.create_task(test2(data))]
finished, unfinished = ioloop.run_until_complete(asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION))
but I don't think it's a proper way to handle conditions.
so I want a basic example of how to create and handle conditions with ayncio.
Upvotes: 0
Views: 502
Reputation: 155216
as soon as one of the tests failed, parent function should return fail and cancel the other test.
asyncio.gather
does that automatically:
loop = asyncio.get_event_loop()
tasks = [loop.create_task(test1(data)), loop.create_task(test2(data))]
try:
loop.run_until_complete(asyncio.gather(*tasks))
except FailException: # use exception raised by the task that fails
print('failed')
When any task executed in asyncio.gather
raises an exception, all other tasks will be canceled using Task.cancel
, and the exception will be propagated to the awaiter of gather
. You don't need a Condition
at all, cancellation will automatically interrupt whatever blocking operation the tasks were waiting on.
Conditions are needed when a task that is otherwise idle (or many such tasks) needs to wait for an event that can happen in some other task. In that case it waits on a condition and is notified of it occurring. If the task is just going about its business, you can cancel it any time you like, or let functions like asyncio.gather
or asyncio.wait_for
do it for you.
Upvotes: 3