diff --git a/serve.py b/serve.py index fc22d9e..1e81363 100755 --- a/serve.py +++ b/serve.py @@ -7,17 +7,15 @@ import base64 import uuid import logging.config import argparse -from concurrent.futures import ThreadPoolExecutor import mimetypes import signal +import asyncio # user installed libraries import tornado.ioloop import tornado.web import tornado.httpserver -from tornado import template, iostream, gen -from tornado.concurrent import run_on_executor -from tornado.platform.asyncio import to_tornado_future +from tornado import template, iostream # this project from learnapp import LearnApp @@ -79,11 +77,14 @@ class LoginHandler(BaseHandler): self.render('login.html', error='') # @gen.coroutine - def post(self): + async def post(self): uid = self.get_body_argument('uid') pw = self.get_body_argument('pw') - if self.learn.login(uid, pw): + loop = asyncio.get_event_loop() + login_ok = await loop.run_in_executor(None, self.learn.login, uid, pw) + + if login_ok: self.set_secure_cookie("user", str(uid), expires_days=30) self.redirect(self.get_argument("next", "/")) else: @@ -179,14 +180,13 @@ class FileHandler(BaseHandler): chunk = f.read(self.chunk_size) while chunk: try: - self.write(chunk) # write the cunk to response + self.write(chunk) # write the chunk to response await self.flush() # flush the current chunk to socket except iostream.StreamClosedError: break # client closed the connection finally: del chunk - await gen.sleep(0.000000001) # 1 nanosecond (hack) - # FIXME in the upcomming tornado 5.0 use `await asyncio.sleep(0)` instead + await asyncio.sleep(0) # 1 nanosecond (hack) chunk = f.read(self.chunk_size) @@ -194,8 +194,6 @@ class FileHandler(BaseHandler): # respond to AJAX to get a JSON question # ---------------------------------------------------------------------------- class QuestionHandler(BaseHandler): - executor = ThreadPoolExecutor() # max_workers=5*n_cpus? - templates = { 'checkbox': 'question-checkbox.html', 'radio': 'question-radio.html', @@ -212,12 +210,6 @@ class QuestionHandler(BaseHandler): # 'alert': '', FIXME } - # Blocking function to be run on the executor - @run_on_executor() - def check_answer(self, user, answer): - return self.learn.check_answer(user, answer) - - # --- get question to render @tornado.web.authenticated def get(self): @@ -255,7 +247,10 @@ class QuestionHandler(BaseHandler): answer = answer[0] # check answer in another thread (nonblocking) - grade = await to_tornado_future(self.check_answer(user, answer)) + loop = asyncio.get_event_loop() + grade = await loop.run_in_executor(None, self.learn.check_answer, user, answer) + + print('grade = ', grade) question = self.learn.get_student_question(user) if grade <= 0.999: # wrong answer @@ -277,7 +272,8 @@ class QuestionHandler(BaseHandler): }) else: # right answer, get next question in the topic template = self.templates[question['type']] - question_html = self.render_string(template, question=question, md=md_to_html) + question_html = self.render_string( + template, question=question, md=md_to_html) self.write({ 'method': 'new_question', 'params': { -- libgit2 0.21.2