title: Retry task after task exception with asyncio.wait
body: <p>I have multiple coroutines that should be run simultaneously, some of which may throw an exception. In those cases the coroutines should be run again. How do I accomplish this? Minimum demo of what I'm trying to do:</p>
  
  <pre><code>import asyncio
  import time
  
  t = time.time()
  
  
  async def c1():
      print("finished c1 {}".format(time.time() - t))
  
  
  async def c2():
      await asyncio.sleep(3)
      print("finished c2 {}".format(time.time() - t))
  
  
  called = False
  
  
  async def c3():
      global called
      # raises an exception the first time it's called
      if not called:
          called = True
          raise RuntimeError("c3 called the first time")
      print("finished c3 {}".format(time.time() - t))
  
  
  async def run():
      pending = {c1(), c2(), c3()}
  
      num_times_called = 0
      while pending:
          num_times_called += 1
          print("{} times called with {} pending tasks: {}".format(num_times_called, len(pending), pending))
  
          finished, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_EXCEPTION)
          for task in finished:
              if task.exception():
                  print("{} got an exception {}, retrying".format(task, task.exception()))
                  pending.add(task)
  
          print("finished {}".format(finished))
  
      print("finished all {}".format(time.time() - t))
  
  
  asyncio.get_event_loop().run_until_complete(run())
  </code></pre>
  
  <p><code>c3()</code> represents that some coroutines will fail and need to be rerun. The problem with the demo is the finished task is finished and has exception set, so when I put it back onto the pending set, the next run loop exits immediately without rerunning <code>c3()</code> because it's already done. </p>
  
  <p>Is there a way to clear the task so that it will run <code>c3()</code> again? I know that the coroutine instance attached to the task cannot be awaited on again else I get </p>
  
  <blockquote>
    <p><code>RuntimeError('cannot reuse already awaited coroutine',)</code></p>
  </blockquote>
  
  <p>which means I have to manually manage a map from coroutine instance to the coroutine that generated it, then retrieve the failed coroutine instance with <code>task._coro</code> - is this right?</p>