Reputation: 16301
I'm running a Python api server with a Tornado application.
My Tornado app uses tornado.web
and is defined like
from tornado import web
def application():
handlers = [
# apis
(r'/api/1', th.APIHandler1),
(r'/api/2', th.APIHandler2)
]
settings = dict()
return web.Application(handlers, **settings)
So it runs in the IOLoop like
app = application()
app.listen(int(PORT))
ioloop.IOLoop.instance().start()
So it is not a WSGI application. The handlers will typically be decorated with the @tornado.web.asynchronous
pattern, and for cpu-intensive task with the @tornado.gen.coroutine
pattern or in some specific case for long duration tasks with the @tornado.concurrent.run_on_executor
decorator to run as a thread in a thread pool. In this specific case I'm using a bounded thread pool executor like:
class MyHandler2(tornado.web.RequestHandler):
executor = BoundedThreadPoolExecutor(max_workers=5)
@tornado.concurrent.run_on_executor
def get(self, *args):
I want to port this to gunicorn
to take advantage of pre-fork workers approach.
A possible solution I have investigated is the gunicorn multi app pattern that should look like:
from routes import Mapper
from test import app as apiHandler1
from test import app as apiHandler2
class Application(object):
def __init__(self):
self.map = Mapper()
self.map.connect('app1', '/api/1', app=apiHandler1)
self.map.connect('app2', '/api/2', app=apiHandler2)
def __call__(self, environ, start_response):
match = self.map.routematch(environ=environ)
if not match:
return self.error404(environ, start_response)
return match[0]['app'](environ, start_response)
app = Application()
There is no specific docs about porting a Tornado asynchronous app to gunicorn wsgi app, so my question is if this approach can be the correct one.
Upvotes: 0
Views: 520
Reputation: 22154
Tornado is not a WSGI-based framework, so it cannot be used in a WSGI application server (it was possible to run a subset of Tornado applications in a WSGI-compatible mode in older versions of Tornado, but this was removed in Tornado 6.0). Gunicorn has a Tornado-specific worker_class that must be used instead.
Upvotes: 1