0

The code below is intended to send multiple HTTP requests asynchronously in a while loop, and depending on the response from each request(request "X" always returns "XXX", "Y" always returns "YYY" and so on), do something and sleep for interval seconds specified for each request.


However, it throws an error...

RuntimeError: cannot reuse already awaited coroutine

Could anyone help me how I could fix the code to realise the intended behaviour?

class Client:
    def __init__(self):
        pass

    async def run_forever(self, coro, interval):
        while True:
            res = await coro
            await self._onresponse(res, interval)

    async def _onresponse(self, res, interval):
        if res == "XXX":
            # ... do something with the resonse ...
            await asyncio.sleep(interval)
        if res == "YYY":
            # ... do something with the resonse ...
            await asyncio.sleep(interval)
        if res == "ZZZ":
            # ... do something with the resonse ...
            await asyncio.sleep(interval)


async def request(something):
    # ... HTTP request using aiohttp library ...
    return response


async def main():
    c = Client()
    await c.run_forever(request("X"), interval=1)
    await c.run_forever(request("Y"), interval=2)
    await c.run_forever(request("Z"), interval=3)
    # ... and more

1 Answer 1

4

As the error says, you can't await a coroutine more than once. Instead of passing a coroutine into run_forever and then awaiting it in a loop, passing the coroutine's argument(s) instead and await a new coroutine each iteration of the loop.

class Client:
    async def run_forever(self, value, interval):
        while True:
            res = await rqequest(value)
            await self._response(response, interval)

You also need to change how you await run_forever. await is blocking, so when you await something with an infinite loop, you'll never reach the next line. Instead, you want to gather multiple coroutines as once.

async def main():
    c = Client()
    await asyncio.gather(
        c.run_forever("X", interval=1),
        c.run_forever("Y", interval=2),
        c.run_forever("Z", interval=3),
    )
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Do you know why we are not allowed to await a coroutine multiple times?
A coroutine will always run only once. In languages that allow multiple awaits your code will still not work since request will be called only thrice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.