title: Python Asyncio producer-consumer workflow congestion / growing queue
body: <p>I have been writing a Python app, where:</p>
  <ul>
  <li>There is an <code>async</code> function <code>producer</code> which listens incoming <code>items</code> over a websocket, and put these <code>items</code> into an <code>queue = asyncio.Queue()</code>.</li>
  <li>There is an <code>async</code> function <code>consumer</code> which does <code>queue.get()</code>, and query <code>item_details</code> over a different websocket connection.</li>
  </ul>
  <p><strong>The problem:</strong> The average speed that putting incoming <code>items</code> into the <code>queue</code> is much higher than the speed of the <code>consumer</code> to <code>get</code> items from the <code>queue</code>, and as a result the <code>queue</code> is piling up after a while.</p>
  <p><strong>Question:</strong> What is the proper way to scale-up <code>consumer</code> <em>without multi-processing</em> and <em>without throttling the incoming connection</em>? I am not yet very proficient with <code>asyncio</code> and <code>threading</code>. I thought of running <code>consumer</code> in separate workers, but as far as I understand asyncio's <code>run_in_executor</code> cannot be used on <code>async</code> functions, and there is also this thing that <code>asyncio.Queue()</code> not being thread-safe.</p>