Tornado Server Experiments Revision as of Saturday, 22 May 2021 at 17:53 UTC

import tornado.httpserver
import tornado.ioloop
import tornado.concurrent
from tornado.options import (
    define,
    options,
    parse_command_line
)
import tornado.web


class SyncHandler(tornado.web.RequestHandler):
    """Simple request handler that blocks the IOLoop
    """
    def get(self, seconds):
        blocking_task(int(seconds))
        self.write("Blocked {}".format(seconds))

class AsyncHandler(tornado.web.RequestHandler):
    """Use Tornado's coroutine generators to handle an incoming request.
       A slow, blocking function is submitted to an execution pool and
       control is released back to the Tornado server's IOLoop to
       service other incoming requests.
    """
    # Create a thread pool
    import concurrent
    executor = concurrent.futures.ThreadPoolExecutor(10)

    @tornado.concurrent.run_on_executor
    def blocking_task(self, n=10):
        from time import sleep
        print("Sleeping {}".format(n))
        sleep(n)
        return n

    @tornado.gen.coroutine
    def get(self, seconds):
        yield self.blocking_task(int(seconds))
        self.write("Blocked {}".format(seconds))

class IndexHandler(tornado.web.RequestHandler):
    """Handle the index page
    """
    def get(self):
        self.write("I'm a Tornado server")

define("port", default=8000, help="Port to run Tornado instance on")
define("reload", default=False, help="Reload server on change")
define("debug", default=False, help="Show debug logs")

if __name__ == '__main__':
    parse_command_line()

    tornado.httpserver.HTTPServer(
        tornado.web.Application(
                    handlers=[
                        (r"/", IndexHandler),
                        (r"/sync\/?(\d+)", SyncHandler),
                        (r"/async\/?(\d+)", AsyncHandler)
                    ],
                    autoreload=options.reload,
                    debug=options.debug,
                )
        ).listen(options.port)

    tornado.ioloop.IOLoop.instance().start()

import tornado.httpserver
import tornado.ioloop
from tornado.options import (
    define,
    options,
    parse_command_line
)
import tornado.web


# Create a thread pool
import concurrent
executor = concurrent.futures.ThreadPoolExecutor(10)

def blocking_task(n=10):
    from time import sleep
    print("Sleeping {}".format(n))
    sleep(n)

class SyncHandler(tornado.web.RequestHandler):
    """Simple request handler that blocks the IOLoop
    """
    def get(self, seconds):
        blocking_task(int(seconds))
        self.write("Blocked {}".format(seconds))

class AsyncHandler(tornado.web.RequestHandler):
    """Use Tornado's coroutine generators to handle an incoming request.
       A slow, blocking function is submitted to an execution pool and
       control is released back to the Tornado server's IOLoop to
       service other incoming requests.

       There's also a @run_on_executor decorator that can be applied
       to the blocking function to prettify things.
       E.g. https://gist.github.com/methane/2185380#comment-1301483

       References
       ----------
       * http://tornado.readthedocs.org/en/latest/guide/coroutines.html
       * http://blog.trukhanov.net/Running-synchronous-code-on-tornado-asynchronously/
       * http://lbolla.info/blog/2013/01/22/blocking-tornado
    """
    @tornado.gen.coroutine
    def get(self, seconds):
        yield executor.submit(blocking_task, int(seconds))
        self.write("Blocked {}".format(seconds))

class IndexHandler(tornado.web.RequestHandler):
    """Handle the index page
    """
    def get(self):
        self.write("I'm a Tornado server")

define("port", default=8000, help="Port to run Tornado instance on")
define("reload", default=False, help="Reload server on change")
define("debug", default=False, help="Show debug logs")

if __name__ == '__main__':
    parse_command_line()

    tornado.httpserver.HTTPServer(
        tornado.web.Application(
                    handlers=[
                        (r"/", IndexHandler),
                        (r"/sync\/?(\d+)", SyncHandler),
                        (r"/async\/?(\d+)", AsyncHandler)
                    ],
                    autoreload=options.reload,
                    debug=options.debug,
                )
        ).listen(options.port)

    tornado.ioloop.IOLoop.instance().start()