strangedev
2/25/2019 - 10:38 AM

An example of asyncio. This starts a long running task concurrently and then schedules a timeout to cancel the task if it didn't complete in

An example of asyncio. This starts a long running task concurrently and then schedules a timeout to cancel the task if it didn't complete in time. Also demonstrates error handling.

import asyncio
import random
from datetime import timedelta
from typing import Coroutine

__author__ = "Noah Hummel"

def schedule_with_timeout(coro: Coroutine, t: timedelta) -> asyncio.Task:
    task = asyncio.create_task(coro)

    async def _timeout():
        await asyncio.sleep(t.seconds)
        task.cancel()

    _ = asyncio.create_task(_timeout())
    return task


async def long_operation_might_fail() -> bool:
    print("CoroutineStart: long_operation_might_fail")
    await asyncio.sleep(random.randint(1, 10))  # operation takes some time
    if random.uniform(0, 1) < 0.9:  # operations fails with 90% likelihood
        raise Exception()
    return True


async def main():
    # schedule long_operation_might_fail to run concurrently
    long_task = schedule_with_timeout(
        long_operation_might_fail(),
        timedelta(seconds=6)
    )

    try:
        print(await long_task)
    except asyncio.CancelledError:
        print("Timeout!")
    except Exception:
        print("Exception!")

if __name__ == "__main__":
    asyncio.run(main())