title: Calling Tornado coroutines from synchronous code
body: <p>This will be a long question, so: </p>
  
  <p><strong>TL;DR:</strong> I have a Python 2.7 threaded network server with a request handler, call stack looks like:</p>
  
  <pre><code>WorkerThread -&gt; requestHandler -&gt; func1 -&gt; func2 -&gt; .. -&gt; func10 -&gt; doStuff -&gt; BlockingIO
  </code></pre>
  
  <p>I want to use Tornado 3.0 IOLoop and change just the server and IO parts:</p>
  
  <pre><code>(IOLoop) -&gt; requestHandler -&gt; func1 -&gt; func2 -&gt; .. -&gt; func10 -&gt; (doStuff) -&gt; (AsyncIO)
  </code></pre>
  
  <p>So all the code stack between requestHandler() and func10() will not change at all. In fact, even doStuff()'s interface won't change, and it will appear to block. However, internally it will use an AsyncIO object (being a Tornado coroutine), and during the async IO operation yield to the IOLoop for execution of other coroutines until the IO operation finishes.</p>
  
  <p>Is this possible?</p>
  
  <hr>
  
  <hr>
  
  <hr>
  
  <p>Now to an almost real example:</p>
  
  <p>I have a network server which receives requests and handles them using a thread pool (or a process pool, doesn't matter as far as this example goes):</p>
  
  <pre><code>def main():
  
      # Main entry point, called below.
  
      # Fake class, you can imagine the internals. We register a request 
      # handler here - handleRequest()
      server = ThreadedServer(handler=handleRequest) 
  
      # Server has a thread pool, each request is handled on a worker thread. 
      # One thread handles network stuff and pushes requests to worker threads
      Server.start()
  
  def handleRequest(server_address):
  
      # This is the request handler, called in the context of a worker 
      # thread, after a network request was received.
  
      # We call the function below. It blocks the thread until it finishes.
      # Not very optimal, since the blocking is network IO bound
      result = doStuff(server_address)
  
      # We use the result somehow, here we print it
      print "Request handled with result: %s" % result
  
  def doStuff(server_address):
  
      # This is called by the request handler
  
      # This is a network bound object, most of its time is spent waiting
      # for the network IO
      net_bound_object = NetBoundSyncObject(server_address)
  
      # This would block, waiting on the network, preventing the thread from 
      # handling other requests
      result = net_bound_object.do_something()
  
      # We have the result, return it
      return result
  
  if __name__ == "__main__":
  
      main()
  </code></pre>
  
  <p>Pretty simple, really.</p>
  
  <p>Now, let's say I've decided I want to refactor my server to use Tornado, using tornado.gen to support asynchronous operations, thus not being so handicapped by network IO. So, this is my new code:</p>
  
  <pre><code>def main():
  
      # Start Tornado's IOLoop, first entering TornadoServer.start() to begin
      # initializing the server and accept requests.
      # server.start is a coroutine that waits for network IO, yielding 
      # control back to the IOLoop until something
      # happens. When something does, it is awakened and schedules a 
      # request handler - handleRequest, and goes back to network IO, 
      # yielding control. Thus, handleRequest is called.
      server = TornadoServer(handler=handleRequest) # fake class again
      IOLoop.instance().add_callback(server.start)
      IOLoop.instance().start()
  
  def handleRequest(server_address):
  
      # This part of the code has not been changed - just the comments.
      # It is now run in the context of an IOLoop callback.
  
      # We call the function above. The interface remains the same. It also seems
      # to block - which is fine, we want to wait for its result to continue processing.
      # However, we want the IOLoop to continue running somehow.
      result = doStuff(server_address)
  
      # We use the result somehow, here we print it
      print "Request handled with result: %s" % result            
  
  def doStuff(server_address):
  
      # This is a network bound object, most of its time is spent waiting for
      # the network IO, however all its methods are coroutines and it yields 
      # while waiting for network IO
      net_bound_object = NetBoundAsyncObject(server_address)
  
      # Now to the problem.
      # doStuff() is a facade - I don't want it to be a coroutine, I want it to hide
      # the implementation details and keep its previous interface.
  
      # However, NetBoundAsyncObject.do_something_async() is a coroutine, and calls
      # coroutines inside it. So it should be called in the context of
      # another coroutine:
      result = yield net_bound_object.do_something_async()
      # but this is wrong here, since we are not a coroutine.
  
      # To properly call it asynchronously, I would need to make doStuff()
      # a coroutine as well, breaking its interface, which would mean that 
      # handleRequest too should now be a coroutine. Not a big change, but imagine
      # that instead of calling doStuff() directly, I had code like:
      # handleRequest -&gt; func1 -&gt; func2 -&gt; func3 -&gt; ... -&gt; func10 -&gt; doStuff
      # so now I'd have to change all these functions to be coroutines as well.
  
      # All of these functions, handleRequest and func1..10, represent a big stack 
      # of code in my real system which is completely synchronous, CPU bound code, 
      # so it has no IO waits anywhere, just code that needs to be run BEFORE and
      # AFTER the network IO bound code finishes, to properly handle the request. 
      # It is well tested, production proven code that requires no functional change,
      # and that doesn't need to be a coroutine. This would be a big refactor.       
  
      # In the code as it is now, result is now returned as a Future:
      result = net_bound_object.do_something_async()
      # I want to be able to do something like:
      IOLoop.instance().wait_for_future(result)
      # Letting the IOLoop run and handle other things in the meanwhile, like
      # network requests, and also my asynchronous code. 
      # When it finishes, I want my wait_for_future() to return and to continue
      # execution with the result accessible in the future object.
  
      # Thus, the changes would be at the top (the TornadoServer vs ThreadedServer)
      # and the bottom (doStuff to use either NetBoundObject or NetBoundAsyncObject),
      # but the middle stack will remain unchanged.
  
      # Return the result of the operation
      return result
  
  if __name__ == "__main__":
  
      main()
  </code></pre>
  
  <p>I know that this is problematic in many ways, mostly because of the call stack. When we do something like:</p>
  
  <pre><code>IOLoop.instance().wait_for_future(result)
  </code></pre>
  
  <p>we have a call stack that looks like this:</p>
  
  <pre><code>IOLoop.main_loop.start() -&gt; handleRequest -&gt; IOLoop.main_loop.wait_for_future() -&gt; other_callbacks..
  </code></pre>
  
  <p>so we could possibly (or even probably) run into situations like:</p>
  
  <pre><code>IOLoop.main_loop.start() -&gt; handleRequest -&gt; IOLoop.main_loop.wait_for_future() -&gt; handleRequest -&gt; IOLoop.main_loop.wait_for_future() -&gt; handleRequest -&gt; IOLoop.main_loop.wait_for_future() -&gt; ...
  </code></pre>
  
  <p>obviously if handleRequest itself becomes a coroutine, then when it itself yields, we have no such deep stack issues.</p>
  
  <p>In an embedded system I once used, using a non-preemptive scheduler, there was no issue at any point whatsoever to return control to the scheduler without stack issues. The scheduler would take the execution context and call stack and store them, and change to another context/stack and continue execution from there. When waiting for events/IO, the scheduler would be triggered and run whatever was in the IO loop. I want something like this in my system, instead of having to change the entire call stack above - converting EVERYTHING to coroutines.</p>
  
  <p>Does any one have any tips, any ideas?</p>