title: Asyncio graceful shutdown for a pushing server
body: <p>Consider (where <code>queue</code> is an <code>asyncio.Queue</code>, and I'm using the asyncio <a href="https://github.com/aaugustin/websockets" rel="nofollow">websockets</a> library which uses the same server interface as <code>asyncio</code> in the standard library):</p>
  
  <pre><code>async def handler(websocket: websockets.WebSocketServerProtocol, path):
      while True:
          data = await queue.get()
          await websocket.send(data)
  </code></pre>
  
  <p>What I'm finding is that the <code>ConnectionClosed</code> exception (triggered either when a client disconnects, and is also used for server shutdown) is only raised, obviously, within the loop when we are awaiting on <code>send()</code>.  This can happen <strong>long</strong> after a websocket client has disconnected, because we will spend most of the time awaiting on <code>queue.get()</code>.</p>
  
  <p>Furthermore, I'm trying to implement graceful shutdown of the server.  That code looks very similar to the standard</p>
  
  <pre><code>server.close()
  loop.run_until_complete(server.wait_closed())
  </code></pre>
  
  <p>The issue is that my websocket handler, i.e., <code>handler()</code>, nevertheless still continues to wait on the <code>queue</code> for more data before raising the exceptions that <code>wait_closed()</code> placed on the event loop.</p>
  
  <p>My <strong>question</strong>: is it correct to introduce the use of <code>wait_for()</code> to make the <code>handler()</code> function more responsive to these management events:</p>
  
  <pre><code>async def handler(websocket: websockets.WebSocketServerProtocol, path):
      while True:
          try:
              data = await loop.wait_for(queue.get(), 5.0)  # 5 seconds
              await websocket.send(data)
          except asyncio.TimeoutError:
              logging.debug('Refreshing the loop')
  </code></pre>
  
  <p>Most of the asyncio examples I've found online have been quite simplistic and don't seem to cover these kinds of issues.</p>
  
  <p>I <em>could</em> also put junk on the queue during my shutdown sequence, which would allow the exception to be raised, but that wouldn't help catching client disconnections earlier.</p>
  
  <p>Any good references with examples would be much appreciated. I'm finding the official asyncio docs somewhat terse.</p>