Kibo
Kibo

Reputation: 888

create and handle conditions with asyncio

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

Answers (1)

user4815162342
user4815162342

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

Related Questions