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 | + | ... | ... |