title: Non-blocking launching of concurrent coroutines in Python
body: <p>I want to execute tasks asynchronously and concurrently. If <code>task1</code> is running when <code>task2</code> arrives, <code>task2</code> is started right away, without waiting for <code>task2</code> to complete. Also, I would like to avoid callbacks with the help of coroutines.</p>
  
  <p>Here's a concurrent solution with callbacks:</p>
  
  <pre><code>def fibonacci(n):
      if n &lt;= 1:
          return 1
      return fibonacci(n - 1) + fibonacci(n - 2)
  
  
  class FibonacciCalculatorFuture:
  
      def __init__(self):
          self.pool = ThreadPoolExecutor(max_workers=2)
  
      @staticmethod
      def calculate(n):
          print(f"started n={n}")
          return fibonacci(n)
  
      def run(self, n):
          future = self.pool.submit(self.calculate, n)
          future.add_done_callback(lambda f: print(f.result()))
  
  
  if __name__ == '__main__':
      calculator = FibonacciCalculatorFuture()
      calculator.run(35)
      calculator.run(32)
      print("initial thread can continue its work")
  </code></pre>
  
  <p>Its output:</p>
  
  <pre><code>started n=35
  started n=32
  initial thread can continue its work
  3524578
  14930352
  </code></pre>
  
  <p>And here's my effort to get rid of callbacks:</p>
  
  <pre><code>class FibonacciCalculatorAsync:
  
      def __init__(self):
          self.pool = ThreadPoolExecutor(max_workers=2)
          self.loop = asyncio.get_event_loop()
  
      @staticmethod
      def calculate_sync(n):
          print(f"started n={n}")
          return fibonacci(n)
  
      async def calculate(self, n):
          result = await self.loop.run_in_executor(self.pool, self.calculate_sync, n)
          print(result)
  
      def run(self, n):
          asyncio.ensure_future(self.calculate(n))
  
  
  if __name__ == '__main__':
      calculator = FibonacciCalculatorAsync()
      calculator.run(35)
      calculator.run(32)
      calculator.loop.run_forever()
      print("initial thread can continue its work")
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>started n=35
  started n=32
  3524578
  14930352
  </code></pre>
  
  <p>In this case initial thread won't be able to go further than <code>loop.run_forever()</code> and hence won't be able to accept new tasks. </p>
  
  <p><strong>So, here's my question</strong>: is there a way to simultaneously:</p>
  
  <ul>
  <li>execute tasks concurrently;</li>
  <li>be able to accept new tasks and schedule them for execution right away (along with already running taks);</li>
  <li>use coroutines and code without callbacks.</li>
  </ul>