2

I have a wrapper function which might run a courutine several times:

async def _request_wraper(self, courutine, attempts=5):
   for i in range(1, attempts):
      try:
         task_result = await asyncio.ensure_future(courutine)
         return task_result
      except SOME_ERRORS:
         do_smth()
         continue 

Corutine might be created from differect async func, which may accept diferent number of necessary/unnecessary arguments. When I have a second loop iteration, I am getting error --> cannot reuse already awaited coroutine

I have tried to make a copy of courutine, but it is not possible with methods copy and deepcopy. What could be possible solution to run corutine twice?

Oleksii
  • 263
  • 1
  • 5
  • 10
  • Related: https://stackoverflow.com/q/51116849/1025391 – moooeeeep Mar 18 '20 at 14:38
  • I saw it, but it doesnt unswer my question. In my case i dont have a unified interface how to supply arguments to async func. Function to run in wrapper may have different args. – Oleksii Mar 18 '20 at 14:43
  • You probably don't want the `1, ` in your call to `range`. That will cause you to make `attempts - 1` attempts. – dirn Mar 18 '20 at 15:04
  • Number of iter is not matter in this particular question – Oleksii Mar 18 '20 at 15:14

1 Answers1

0

As you already found out, you can't await a coroutine many times. It simply doesn't make sense, coroutines aren't functions.

It seems what you're really trying to do is retry an async function call with arbitrary arguments. You can use arbitrary argument lists (*args) and the keyword argument equivalent (**kwargs) to capture all arguments and pass them to the function.

async def retry(async_function, *args, **kwargs, attempts=5):
  for i in range(attempts):
    try:
      return await async_function(*args, **kwargs)
    except Exception:
      pass  # (you should probably handle the error here instead of ignoring it)
Tulir
  • 878
  • 11
  • 20