Commit ae1ca233201c55a7c7fd6007964a9699192e7c42
1 parent
7f9b7abd
Exists in
dev
update running tornado to use asyncio event loop
Showing
2 changed files
with
55 additions
and
23 deletions
Show diff stats
aprendizations/main.py
| ... | ... | @@ -7,6 +7,7 @@ Setup configurations and then runs the application. |
| 7 | 7 | |
| 8 | 8 | # python standard library |
| 9 | 9 | import argparse |
| 10 | +import asyncio | |
| 10 | 11 | import logging |
| 11 | 12 | import logging.config |
| 12 | 13 | from os import environ, path |
| ... | ... | @@ -16,7 +17,7 @@ from typing import Any, Dict |
| 16 | 17 | |
| 17 | 18 | # this project |
| 18 | 19 | from .learnapp import LearnApp, LearnException |
| 19 | -from .serve import run_webserver | |
| 20 | +from .serve import webserver | |
| 20 | 21 | from .tools import load_yaml |
| 21 | 22 | from . import APP_NAME, APP_VERSION |
| 22 | 23 | |
| ... | ... | @@ -179,17 +180,19 @@ def main(): |
| 179 | 180 | |
| 180 | 181 | # --- start application -------------------------------------------------- |
| 181 | 182 | try: |
| 182 | - learnapp = LearnApp(courses=arg.courses, | |
| 183 | - prefix=arg.prefix, | |
| 184 | - dbase=arg.db, | |
| 185 | - check=arg.check) | |
| 183 | + app = LearnApp(courses=arg.courses, | |
| 184 | + prefix=arg.prefix, | |
| 185 | + dbase=arg.db, | |
| 186 | + check=arg.check) | |
| 186 | 187 | except LearnException: |
| 187 | 188 | logging.critical('Failed to start application') |
| 188 | 189 | sys.exit(1) |
| 189 | 190 | logging.info('LearnApp started') |
| 190 | 191 | |
| 191 | 192 | # --- run webserver forever ---------------------------------------------- |
| 192 | - run_webserver(app=learnapp, ssl=ssl_ctx, port=arg.port, debug=arg.debug) | |
| 193 | + asyncio.run(webserver(app=app, ssl=ssl_ctx, port=arg.port, debug=arg.debug)) | |
| 194 | + | |
| 195 | + logging.critical('Webserver stopped.') | |
| 193 | 196 | |
| 194 | 197 | |
| 195 | 198 | # ---------------------------------------------------------------------------- | ... | ... |
aprendizations/serve.py
| ... | ... | @@ -4,6 +4,7 @@ Webserver |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | # python standard library |
| 7 | +import asyncio | |
| 7 | 8 | import base64 |
| 8 | 9 | import functools |
| 9 | 10 | from logging import getLogger |
| ... | ... | @@ -58,8 +59,9 @@ class WebApplication(tornado.web.Application): |
| 58 | 59 | (r'/rankings', RankingsHandler), # rankings table |
| 59 | 60 | (r'/topic/(.+)', TopicHandler), # start topic |
| 60 | 61 | (r'/file/(.+)', FileHandler), # serve file |
| 61 | - (r'/courses', CoursesHandler), # show list of courses | |
| 62 | - (r'/course/(.*)', CourseHandler), # show course topics | |
| 62 | + (r'/courses', CoursesHandler), # show available courses | |
| 63 | + (r'/course/(.*)', CourseHandler), # show topics from course | |
| 64 | + (r'/course2/(.*)', CourseHandler2), # show topics from course FIXME | |
| 63 | 65 | (r'/', RootHandler), # redirects |
| 64 | 66 | ] |
| 65 | 67 | settings = { |
| ... | ... | @@ -241,9 +243,38 @@ class CoursesHandler(BaseHandler): |
| 241 | 243 | |
| 242 | 244 | |
| 243 | 245 | # ============================================================================ |
| 246 | +class CourseHandler2(BaseHandler): | |
| 247 | + @tornado.web.authenticated | |
| 248 | + def get(self, course_id) -> None: | |
| 249 | + ''' | |
| 250 | + Handles get /course/... | |
| 251 | + Starts a given course and show list of topics | |
| 252 | + ''' | |
| 253 | + uid = self.current_user | |
| 254 | + logger.debug('[CourseHandler2] uid="%s", course_id="%s"', uid, course_id) | |
| 255 | + | |
| 256 | + if course_id == '': | |
| 257 | + course_id = self.learn.get_current_course_id(uid) | |
| 258 | + | |
| 259 | + try: | |
| 260 | + self.learn.start_course(uid, course_id) | |
| 261 | + except LearnException: | |
| 262 | + self.redirect('/courses') | |
| 263 | + | |
| 264 | + # print(self.learn.get_course(course_id)) | |
| 265 | + self.render('maintopics-table2.html', | |
| 266 | + appname=APP_NAME, | |
| 267 | + uid=uid, | |
| 268 | + name=self.learn.get_student_name(uid), | |
| 269 | + state=self.learn.get_student_state(uid), | |
| 270 | + course_id=course_id, | |
| 271 | + course=self.learn.get_course(course_id) | |
| 272 | + ) | |
| 273 | + | |
| 274 | +# ============================================================================ | |
| 244 | 275 | class CourseHandler(BaseHandler): |
| 245 | 276 | ''' |
| 246 | - Handles a particular course to show the topics table | |
| 277 | + Show topics for a particular course | |
| 247 | 278 | ''' |
| 248 | 279 | |
| 249 | 280 | @tornado.web.authenticated |
| ... | ... | @@ -253,6 +284,8 @@ class CourseHandler(BaseHandler): |
| 253 | 284 | Starts a given course and show list of topics |
| 254 | 285 | ''' |
| 255 | 286 | uid = self.current_user |
| 287 | + logger.debug('[CourseHandler] uid="%s", course_id="%s"', uid, course_id) | |
| 288 | + | |
| 256 | 289 | if course_id == '': |
| 257 | 290 | course_id = self.learn.get_current_course_id(uid) |
| 258 | 291 | |
| ... | ... | @@ -286,7 +319,7 @@ class TopicHandler(BaseHandler): |
| 286 | 319 | Starts a given topic |
| 287 | 320 | ''' |
| 288 | 321 | uid = self.current_user |
| 289 | - logger.debug('[TopicHandler.get] %s', topic) | |
| 322 | + logger.debug('[TopicHandler] %s', topic) | |
| 290 | 323 | try: |
| 291 | 324 | await self.learn.start_topic(uid, topic) # FIXME GET should not modify state... |
| 292 | 325 | except KeyError: |
| ... | ... | @@ -315,8 +348,8 @@ class FileHandler(BaseHandler): |
| 315 | 348 | public_dir = self.learn.get_current_public_dir(uid) |
| 316 | 349 | filepath = expanduser(join(public_dir, filename)) |
| 317 | 350 | |
| 318 | - logger.debug('uid=%s, public_dir=%s, filepath=%s', uid, public_dir, | |
| 319 | - filepath) | |
| 351 | + logger.debug('[FileHandler] uid=%s, public_dir=%s, filepath=%s', | |
| 352 | + uid, public_dir, filepath) | |
| 320 | 353 | try: |
| 321 | 354 | with open(filepath, 'rb') as file: |
| 322 | 355 | data = file.read() |
| ... | ... | @@ -356,7 +389,7 @@ class QuestionHandler(BaseHandler): |
| 356 | 389 | ''' |
| 357 | 390 | Get question to render or an animated trophy if no more questions. |
| 358 | 391 | ''' |
| 359 | - logger.debug('[QuestionHandler.get]') | |
| 392 | + logger.debug('[QuestionHandler]') | |
| 360 | 393 | user = self.current_user |
| 361 | 394 | question = await self.learn.get_question(user) |
| 362 | 395 | |
| ... | ... | @@ -396,7 +429,7 @@ class QuestionHandler(BaseHandler): |
| 396 | 429 | user = self.current_user |
| 397 | 430 | answer = self.get_body_arguments('answer') # list |
| 398 | 431 | qid = self.get_body_arguments('qid')[0] |
| 399 | - # logger.debug('[QuestionHandler] answer=%s', answer) | |
| 432 | + logger.debug('[QuestionHandler] answer=%s', answer) | |
| 400 | 433 | |
| 401 | 434 | # --- check if browser opened different questions simultaneously |
| 402 | 435 | if qid != self.learn.get_current_question_id(user): |
| ... | ... | @@ -486,9 +519,9 @@ def signal_handler(*_) -> None: |
| 486 | 519 | |
| 487 | 520 | |
| 488 | 521 | # ---------------------------------------------------------------------------- |
| 489 | -def run_webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: | |
| 522 | +async def webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: | |
| 490 | 523 | ''' |
| 491 | - Starts and runs webserver until a SIGINT signal (Ctrl-C) is received. | |
| 524 | + Runs webserver until a SIGINT signal (Ctrl-C) is received. | |
| 492 | 525 | ''' |
| 493 | 526 | |
| 494 | 527 | # --- create web application |
| ... | ... | @@ -517,10 +550,6 @@ def run_webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: |
| 517 | 550 | # --- set signal handler for Control-C |
| 518 | 551 | signal.signal(signal.SIGINT, signal_handler) |
| 519 | 552 | |
| 520 | - # --- run tornado webserver | |
| 521 | - try: | |
| 522 | - tornado.ioloop.IOLoop.current().start() # running... | |
| 523 | - except Exception: | |
| 524 | - logger.critical('Webserver stopped.') | |
| 525 | - tornado.ioloop.IOLoop.current().stop() | |
| 526 | - raise | |
| 553 | + # --- run event loop (and tornado webserver) | |
| 554 | + await asyncio.Event().wait() | |
| 555 | + | ... | ... |