title: Why should asyncio.StreamWriter.drain be explicitly called?
body: <p>From <a href="https://docs.python.org/3/library/asyncio-stream.html#asyncio.StreamWriter.write" rel="noreferrer">doc</a>:</p>
  <blockquote>
  <p>write(data)</p>
  <pre><code>Write data to the stream.
  
  This method is not subject to flow control. Calls to write() should be followed by drain().
  </code></pre>
  <p>coroutine drain()</p>
  <pre><code>Wait until it is appropriate to resume writing to the stream. Example:
  
  writer.write(data)
  await writer.drain()
  </code></pre>
  </blockquote>
  <p>From what I understand,</p>
  <ul>
  <li>You need to call <code>drain</code> every time <code>write</code> is called.</li>
  <li>If not I guess, <code>write</code> will block the loop thread</li>
  </ul>
  <p>Then why is write not a coroutine that calls it automatically? Why would one call <code>write</code> without having to drain? I can think of two cases</p>
  <ol>
  <li>You want to <code>write</code> and <code>close</code> immediately</li>
  <li>You have to buffer some data before the message it is complete.</li>
  </ol>
  <p>First one is a special case, I think we can have a different API. Buffering should be handled inside write function and application should not care.</p>
  <hr />
  <p>Let me put the question differently. What is the drawback of doing this? Does the python3.8 version effectively do this?</p>
  <pre><code>async def awrite(writer, data):
      writer.write(data)
      await writer.drain()
  </code></pre>
  <p>Note: <code>drain</code> doc explicitly states the below:</p>
  <blockquote>
  <p>When there is nothing to wait for, the <code>drain()</code> returns immediately.</p>
  </blockquote>
  <hr />
  <p>Reading the answer and links again, I think the functions work like this. <strong>Note</strong>: Check accepted answer for more accurate version.</p>
  <pre><code>def write(data):
      remaining = socket.try_write(data)
      if remaining:
          _pendingbuffer.append(remaining) # Buffer will keep growing if other side is slow and we have a lot of data
  
  async def drain():
      if len(_pendingbuffer) &lt; BUF_LIMIT:
          return
      await wait_until_other_side_is_up_to_speed()
      assert len(_pendingbuffer) &lt; BUF_LIMIT
  
  async def awrite(writer, data):
      writer.write(data)
      await writer.drain()        
  </code></pre>
  <p>So when to use what:</p>
  <ol>
  <li>When the data is not continuous, Like responding to an HTTP request. We just need to send some data and don't care about when it is reached and memory is not a concern - Just use <code>write</code></li>
  <li>Same as above but memory is a concern, use <code>awrite</code></li>
  <li>When streaming data to a large number of clients (e.g. some live stream or a huge file). If the data is duplicated in each of the connection's buffers, it will definitely overflow RAM. In this case, write a loop that takes a chunk of data each iteration and call <code>awrite</code>. In case of a huge file, <code>loop.sendfile</code> is better if available.</li>
  </ol>