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,6 +7,7 @@ Setup configurations and then runs the application. | ||
7 | 7 | ||
8 | # python standard library | 8 | # python standard library |
9 | import argparse | 9 | import argparse |
10 | +import asyncio | ||
10 | import logging | 11 | import logging |
11 | import logging.config | 12 | import logging.config |
12 | from os import environ, path | 13 | from os import environ, path |
@@ -16,7 +17,7 @@ from typing import Any, Dict | @@ -16,7 +17,7 @@ from typing import Any, Dict | ||
16 | 17 | ||
17 | # this project | 18 | # this project |
18 | from .learnapp import LearnApp, LearnException | 19 | from .learnapp import LearnApp, LearnException |
19 | -from .serve import run_webserver | 20 | +from .serve import webserver |
20 | from .tools import load_yaml | 21 | from .tools import load_yaml |
21 | from . import APP_NAME, APP_VERSION | 22 | from . import APP_NAME, APP_VERSION |
22 | 23 | ||
@@ -179,17 +180,19 @@ def main(): | @@ -179,17 +180,19 @@ def main(): | ||
179 | 180 | ||
180 | # --- start application -------------------------------------------------- | 181 | # --- start application -------------------------------------------------- |
181 | try: | 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 | except LearnException: | 187 | except LearnException: |
187 | logging.critical('Failed to start application') | 188 | logging.critical('Failed to start application') |
188 | sys.exit(1) | 189 | sys.exit(1) |
189 | logging.info('LearnApp started') | 190 | logging.info('LearnApp started') |
190 | 191 | ||
191 | # --- run webserver forever ---------------------------------------------- | 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,6 +4,7 @@ Webserver | ||
4 | 4 | ||
5 | 5 | ||
6 | # python standard library | 6 | # python standard library |
7 | +import asyncio | ||
7 | import base64 | 8 | import base64 |
8 | import functools | 9 | import functools |
9 | from logging import getLogger | 10 | from logging import getLogger |
@@ -58,8 +59,9 @@ class WebApplication(tornado.web.Application): | @@ -58,8 +59,9 @@ class WebApplication(tornado.web.Application): | ||
58 | (r'/rankings', RankingsHandler), # rankings table | 59 | (r'/rankings', RankingsHandler), # rankings table |
59 | (r'/topic/(.+)', TopicHandler), # start topic | 60 | (r'/topic/(.+)', TopicHandler), # start topic |
60 | (r'/file/(.+)', FileHandler), # serve file | 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 | (r'/', RootHandler), # redirects | 65 | (r'/', RootHandler), # redirects |
64 | ] | 66 | ] |
65 | settings = { | 67 | settings = { |
@@ -241,9 +243,38 @@ class CoursesHandler(BaseHandler): | @@ -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 | class CourseHandler(BaseHandler): | 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 | @tornado.web.authenticated | 280 | @tornado.web.authenticated |
@@ -253,6 +284,8 @@ class CourseHandler(BaseHandler): | @@ -253,6 +284,8 @@ class CourseHandler(BaseHandler): | ||
253 | Starts a given course and show list of topics | 284 | Starts a given course and show list of topics |
254 | ''' | 285 | ''' |
255 | uid = self.current_user | 286 | uid = self.current_user |
287 | + logger.debug('[CourseHandler] uid="%s", course_id="%s"', uid, course_id) | ||
288 | + | ||
256 | if course_id == '': | 289 | if course_id == '': |
257 | course_id = self.learn.get_current_course_id(uid) | 290 | course_id = self.learn.get_current_course_id(uid) |
258 | 291 | ||
@@ -286,7 +319,7 @@ class TopicHandler(BaseHandler): | @@ -286,7 +319,7 @@ class TopicHandler(BaseHandler): | ||
286 | Starts a given topic | 319 | Starts a given topic |
287 | ''' | 320 | ''' |
288 | uid = self.current_user | 321 | uid = self.current_user |
289 | - logger.debug('[TopicHandler.get] %s', topic) | 322 | + logger.debug('[TopicHandler] %s', topic) |
290 | try: | 323 | try: |
291 | await self.learn.start_topic(uid, topic) # FIXME GET should not modify state... | 324 | await self.learn.start_topic(uid, topic) # FIXME GET should not modify state... |
292 | except KeyError: | 325 | except KeyError: |
@@ -315,8 +348,8 @@ class FileHandler(BaseHandler): | @@ -315,8 +348,8 @@ class FileHandler(BaseHandler): | ||
315 | public_dir = self.learn.get_current_public_dir(uid) | 348 | public_dir = self.learn.get_current_public_dir(uid) |
316 | filepath = expanduser(join(public_dir, filename)) | 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 | try: | 353 | try: |
321 | with open(filepath, 'rb') as file: | 354 | with open(filepath, 'rb') as file: |
322 | data = file.read() | 355 | data = file.read() |
@@ -356,7 +389,7 @@ class QuestionHandler(BaseHandler): | @@ -356,7 +389,7 @@ class QuestionHandler(BaseHandler): | ||
356 | ''' | 389 | ''' |
357 | Get question to render or an animated trophy if no more questions. | 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 | user = self.current_user | 393 | user = self.current_user |
361 | question = await self.learn.get_question(user) | 394 | question = await self.learn.get_question(user) |
362 | 395 | ||
@@ -396,7 +429,7 @@ class QuestionHandler(BaseHandler): | @@ -396,7 +429,7 @@ class QuestionHandler(BaseHandler): | ||
396 | user = self.current_user | 429 | user = self.current_user |
397 | answer = self.get_body_arguments('answer') # list | 430 | answer = self.get_body_arguments('answer') # list |
398 | qid = self.get_body_arguments('qid')[0] | 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 | # --- check if browser opened different questions simultaneously | 434 | # --- check if browser opened different questions simultaneously |
402 | if qid != self.learn.get_current_question_id(user): | 435 | if qid != self.learn.get_current_question_id(user): |
@@ -486,9 +519,9 @@ def signal_handler(*_) -> None: | @@ -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 | # --- create web application | 527 | # --- create web application |
@@ -517,10 +550,6 @@ def run_webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: | @@ -517,10 +550,6 @@ def run_webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: | ||
517 | # --- set signal handler for Control-C | 550 | # --- set signal handler for Control-C |
518 | signal.signal(signal.SIGINT, signal_handler) | 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 | + |