High-performance Tornado
Assuming you have a database that can ahndle it, serving 100-500 requests/second from a Tornado web app shouldn't be hard. The best part is that Tornaod 4 makes writing asychrnous code so easy and straightforward that it's a delight to write such methods now. My favorite seature that's been added has been (Futures)[http://www.tornadoweb.org/en/stable/concurrent.html#tornado-concurrent-work-with-threads-and-futures] and I've replaced all callback methods by wrapping them into futures.
Generally when I use Tornado, when I know that:
-
the aplication is heavily I/O-bound. Maybe it's making calls to databases, cache servers, maybe it's fetching URLs from the web.
-
CPU-expensize work wil be offloaded somewhere else or is disallowed.
Here is the pattern I use to organize my python code:
-
isolate every database call that the handler makes, then decorate it with
@concurrent.run_on_executor
. This decorator simply tells Tornado to run this method asynchronously on an executor. The executor may be a thread or process-based. In our case we can use the thread-based executor since we don't have to worry about acquiring the GIL when waiting for I/O. -
decorate every method that calls those database-related methods with
gen.coroutine