Flask and Tornado Applciation does not handle multiple concurrent requests
<p>I am running a simple Flask app with Tornado, but the view only handles one request at a time.  How can I make it handle multiple concurrent requests?</p>

<p>The fix I'm using is to fork and use the multiple processes to handle requests, but I don't like that solution.</p>

<pre><code>from flask import Flask

app = Flask(__name__)

@app.route('/flask')
def hello_world():
    return 'This comes from Flask ^_^'

from tornado.wsgi import WSGIContainer
from tornado.ioloop import IOLoop
from tornado.web import FallbackHandler, RequestHandler, Application
from flasky import app

class MainHandler(RequestHandler):
  def get(self):
    self.write("This message comes from Tornado ^_^")

tr = WSGIContainer(app)

application = Application([
    (r"/tornado", MainHandler),
    (r".*", FallbackHandler, dict(fallback=tr)),
])

if __name__ == "__main__":
    application.listen(8000)
    IOLoop.instance().start()
</code></pre>

<p>Your fix of spawning processes is correct in as much as using WSGI with Tornado is "correct".  WSGI is a synchronous protocol: one worker handles one request at a time.  Flask doesn't know about Tornado, so it can't play nice with it by using coroutines: handling the request happens synchronously.</p>

<p><a href="http://www.tornadoweb.org/en/stable/wsgi.html#running-wsgi-apps-on-tornado-servers" rel="nofollow">Tornado has a big warning in their docs about this exact thing.</a></p>

<blockquote>
  <p>WSGI is a <em>synchronous</em> interface, while Tornadoâs concurrency model is based on single-threaded asynchronous execution. This means that running a WSGI app with Tornadoâs <code>WSGIContainer</code> is <em>less scalable</em> than running the same app in a multi-threaded WSGI server like <a href="http://gunicorn.org/" rel="nofollow">gunicorn</a> or <a href="http://uwsgi-docs.readthedocs.io/en/latest/" rel="nofollow">uwsgi</a>. Use <code>WSGIContainer</code> only when there are benefits to combining Tornado and WSGI in the same process that outweigh the reduced scalability.</p>
</blockquote>

<p>In other words: to handle more concurrent requests with a WSGI application, spawn more workers.  The type of worker also matters: threads vs. processes vs. eventlets all have tradeoffs.  You're spawning workers by creating processes yourself, but it's more common to use a WSGI server such as uWSGI or Gunicorn.</p>

python flask tornado