aboutsummaryrefslogtreecommitdiff
path: root/app/handlers/base.py
diff options
context:
space:
mode:
authorMilo Casagrande <milo@ubuntu.com>2014-04-01 13:44:49 +0200
committerMilo Casagrande <milo@ubuntu.com>2014-04-01 13:44:49 +0200
commit4fd5d67dd31a52522ee9e49bae0ce88d2aa5f23d (patch)
treec5ddbe32086a2d847e53f487fb8116d061996589 /app/handlers/base.py
parent4dd0ce7e8b800e3db36b7ad67dc5b0c7586f1ed3 (diff)
Make functions async.
* Use an external ThreadPoolExecutor to run database queries, and the other sync operation.
Diffstat (limited to 'app/handlers/base.py')
-rw-r--r--app/handlers/base.py87
1 files changed, 52 insertions, 35 deletions
diff --git a/app/handlers/base.py b/app/handlers/base.py
index e5d0d4f..95a9968 100644
--- a/app/handlers/base.py
+++ b/app/handlers/base.py
@@ -15,24 +15,23 @@
"""The base RequestHandler that all subclasses should inherit from."""
-import types
import httplib
+import tornado
+import types
from bson.json_util import dumps
-from tornado import gen
+from functools import partial
from tornado.web import (
RequestHandler,
asynchronous,
)
-from pymongo.cursor import Cursor
-
from models import DB_NAME
-from utils.validator import is_valid_json_put
from utils.db import (
- find_async,
- find_one_async,
+ find,
+ find_one,
)
+from utils.validator import is_valid_json_put
# Default and maximum limit for how many results to get back from the db.
DEFAULT_LIMIT = 20
@@ -48,6 +47,10 @@ class BaseHandler(RequestHandler):
super(BaseHandler, self).__init__(application, request, **kwargs)
@property
+ def executor(self):
+ return self.settings['executor']
+
+ @property
def collection(self):
"""The name of the database collection for this object."""
return None
@@ -113,31 +116,51 @@ class BaseHandler(RequestHandler):
:return A (int, str) tuple composed of the status code, and the
message.
"""
- valid_response = (200, self._get_status_message(200))
+ status, message = 200, self._get_status_message(200)
- if isinstance(response, types.DictionaryType):
- valid_response = (200, dumps(response))
+ if isinstance(response, (types.DictionaryType, types.ListType)):
+ status, message = 200, dumps(response)
elif isinstance(response, types.IntType):
- valid_response = (response, self._get_status_message(response))
- elif isinstance(response, Cursor):
- valid_response = (200, dumps(response))
+ status, message = response, self._get_status_message(response)
elif isinstance(response, types.NoneType):
- valid_response = (404, self._get_status_message(404))
+ status, message = 404, self._get_status_message(404)
+
+ self.set_status(status)
+ self.write(dict(status=status, message=message))
+ self.finish()
- return valid_response
+ def _get_callback(self, limit, result):
+ """Callback used for GET operations.
+
+ :param limit: The number of elements returned.
+ :param result: The result from the future instance.
+ """
+ response = dict(
+ status=200, limit=limit, message=dumps(result)
+ )
+
+ self.set_status(200)
+ self.write(response)
+ self.finish()
+
+ def _post_callback(self, result):
+ """Callback used for POST operations.
+
+ :param result: The result from the future instance.
+ """
+ self._create_valid_response(result)
@asynchronous
- @gen.engine
def get(self, *args, **kwargs):
if kwargs and kwargs['id']:
- result = yield gen.Task(
- find_one_async,
- self.collection,
- kwargs['id'],
- )
- status_code, response = self._create_valid_response(result)
- response = dict(code=status_code, message=response)
+ self.executor.submit(
+ partial(find_one, self.collection, kwargs['id'])
+ ).add_done_callback(
+ lambda future: tornado.ioloop.IOLoop.instance().add_callback(
+ partial(self._create_valid_response, future.result())
+ )
+ )
else:
skip = int(self.get_query_argument('skip', default=0))
limit = int(
@@ -146,20 +169,14 @@ class BaseHandler(RequestHandler):
if limit > MAX_LIMIT:
limit = MAX_LIMIT
- result = yield gen.Task(
- find_async,
- self.collection,
- limit,
- skip,
+ self.executor.submit(
+ partial(find, self.collection, limit, skip)
+ ).add_done_callback(
+ lambda future:
+ tornado.ioloop.IOLoop.instance().add_callback(
+ partial(self._get_callback, limit, future.result()))
)
- status_code, response = self._create_valid_response(result)
- response = dict(code=status_code, limit=limit, message=response)
-
- self.set_status(status_code)
- self.write(response)
- self.finish()
-
def write_error(self, status_code, **kwargs):
status_message = self._get_status_message(status_code)