Created
August 21, 2014 12:21
-
-
Save mosquito/21dfe6a16e497e8dc7c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
import traceback | |
from tornado.ioloop import IOLoop | |
from tornado.web import asynchronous, RequestHandler, HTTPError | |
import logging | |
log = logging.getLogger('handlers.lib.threaded') | |
class ThreadPoolHandler(object): | |
POOL = None | |
def run_background(self, func, callback, args=(), kwds={}): | |
def _callback(result): | |
IOLoop.instance().add_callback(lambda: callback(result)) | |
self.POOL.apply_async(func, args, kwds, callback=_callback) | |
class ThreadedHandler(ThreadPoolHandler, RequestHandler): | |
def initialize(self): | |
self.pool = self.POOL | |
self.manual_finishing = False | |
@asynchronous | |
def get(self, *args, **kwargs): | |
self.run_background(self._do_async, callback=self._on_done, args=args, kwds=kwargs) | |
@asynchronous | |
def post(self, *args, **kwargs): | |
self.run_background(self._do_async, callback=self._on_done, args=args, kwds=kwargs) | |
def _do_async(self, *args, **kwargs): | |
try: | |
response = self.do_async(*args, **kwargs) | |
return response | |
except HTTPError as e: | |
log.info('Request return HTTPError({0}, {1})'.format(e.status_code, e.reason)) | |
return e | |
except Exception as e: | |
log.debug("Async thread return exception: {0}".format(traceback.format_exc())) | |
log.error("Async thread error: {0}".format(repr(e))) | |
return e | |
def do_async(self): | |
raise NotImplementedError("You must override this method") | |
def on_done(self, result): | |
raise NotImplementedError("You must override this method") | |
def _on_done(self, result): | |
if isinstance(result, HTTPError): | |
self.send_error(result.status_code) | |
return | |
elif isinstance(result, Exception): | |
self.send_error(500) | |
return | |
self.on_done(result) | |
if not self._finished and not self.manual_finishing: | |
return self.finish() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment