title: Event loop exception after program finishes
body: <p>W.r.t. Łukasz' tutorial on <a href="https://youtu.be/-CzqsgaXUM8?t=2279" rel="nofollow noreferrer">Youtube</a> for a simple web-crawler, the following code gives <code>RuntimeError: Event loop is closed</code>. This happens after the code runs successfully and prints out the time taken to complete the program.</p>
  <pre><code>import asyncio
  import time
  from typing import Callable, Coroutine
  import httpx
  
  addr = 'https://langa.pl/crawl'
  
  
  async def progress(
      url: str,
      algo: Callable[..., Coroutine],
  ) -&gt; None:
  
      # store create_task into a variable
      task = asyncio.create_task(
          algo(url),
          name=url,
      )
  
      todo.add(task)  # add task to todo
      start = time.time()
  
      while len(todo):
  
          done, _pending = await asyncio.wait(todo, timeout=0.5)
  
          # cleanup todo by removing the done task
          todo.difference_update(done)
  
          # report completed urls
          urls = (t.get_name() for t in todo)
  
          # prints the current status
          print(f&quot;{len(todo)}: &quot; + &quot; &quot;.join(sorted(urls))[-75:])
  
      end = time.time()
      print(f&quot;Took {int(end-start)} seconds&quot;)
  
  
  async def crawl3(
      prefix: str, url: str = &quot;&quot;,
  ) -&gt; None:
      url = url or prefix
      client = httpx.AsyncClient()
      try:
          res = await client.get(url)
      finally:
          await client.aclose()
  
      for line in res.text.splitlines():
          if line.startswith(prefix):
              task = asyncio.create_task(
                  crawl3(prefix, line),
                  name=line,
              )
  
              todo.add(task)
  
  todo = set()
  asyncio.run(progress(addr, crawl3))
  </code></pre>
  <p>Why is this happening? What needs to be changed in the code?</p>