From 361f8245079b625560449324faf111ed6fcf3b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Sun, 4 Oct 2015 19:43:09 +0200 Subject: Unification of language session implementations. Added load_problem and end_problem actions so handlers get appropriately created and destroyed upon loading and unloading the problem solving screen. --- server/user_session.py | 85 +++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 43 deletions(-) (limited to 'server/user_session.py') diff --git a/server/user_session.py b/server/user_session.py index f53ae57..d80cedd 100644 --- a/server/user_session.py +++ b/server/user_session.py @@ -5,12 +5,8 @@ import threading # multiprocessing.managers.BaseManager uses threading to serve import hashlib import base64 import random -from . import prolog_session -from . import python_session -from . import robot_session -from . import problems -from . import handlers import db +import server from errors.session import NoSuchSession, AuthenticationFailed import psycopg2.extras @@ -32,9 +28,7 @@ class UserSession(object): self.sid = uuid.uuid4().hex self.uid = uid self.username = username - self.prolog_session = None - self.python_session = None - self.robot_session = None + self._lang_session = None self.settings = settings def destroy(self): @@ -42,15 +36,9 @@ class UserSession(object): with self._access_lock: with module_access_lock: del sessions[self.sid] - if self.prolog_session is not None: - self.prolog_session.end() - self.prolog_session = None - if self.python_session is not None: - self.python_session.destroy() - self.python_session = None - if self.robot_session is not None: - self.robot_session.destroy() - self.robot_session = None + if self._lang_session is not None: + self._lang_session.destroy() + self._lang_session = None # TODO: add any cleanups as features are added! def get_sid(self): @@ -77,29 +65,46 @@ class UserSession(object): conn.commit() db.return_connection(conn) - - def get_prolog(self): + def load_language_session(self, problem_id): with self._access_lock: - if self.prolog_session is None: - self.prolog_session = prolog_session.PrologSession() # lazy init - return self.prolog_session + if self._lang_session is not None: + self._lang_session.destroy() + self._lang_session = None + conn = db.get_connection() + try: + cur = conn.cursor() + try: + cur.execute("select l.identifier, g.identifier, p.identifier from problem p inner join language l on l.id = p.language_id inner join problem_group g on g.id = p.problem_group_id where p.id = %s", (problem_id,)) + row = cur.fetchone() + if not row: + return None + language_identifier = row[0] + group_identifier = row[1] + problem_identifier = row[2] + handler = server.language_session_handlers.get(language_identifier) + if not handler: + return None + self._lang_session = handler(self, problem_id, language_identifier, group_identifier, problem_identifier) + return self._lang_session + finally: + cur.close() + finally: + conn.commit() + db.return_connection(conn) - def get_python(self): + def end_language_session(self): with self._access_lock: - if self.python_session is None: - self.python_session = python_session.PythonSession( - output_cb=lambda text: self.send({'event': 'terminal_output', 'text': text})) - return self.python_session + if self._lang_session is not None: + self._lang_session.destroy() + self._lang_session = None - def get_robot(self): + def current_language_session(self): with self._access_lock: - if self.robot_session is None: - self.robot_session = robot_session.RobotSession() - return self.robot_session + return self._lang_session def get_problem_data(self, language, problem_group, problem): - mod = problems.load_problem(language, problem_group, problem, 'sl') - mod_language = problems.load_language(language, 'sl') + mod = server.problems.load_problem(language, problem_group, problem, 'sl') + mod_language = server.problems.load_language(language, 'sl') # Get generic and problem-specific hints. hint = dict(mod_language.hint) @@ -171,19 +176,13 @@ class UserSession(object): :return: None """ json_obj['sid'] = self.sid - handlers.send(None, self.sid, json_obj) + server.handlers.send(None, self.sid, json_obj) def __del__(self): # no locking needed if GC is removing us, as there cannot be any concurrent access by definition - if hasattr(self, 'prolog_session') and (self.prolog_session is not None): - self.prolog_session.end() - self.prolog_session = None - if hasattr(self, 'python_session') and (self.python_session is not None): - self.python_session.destroy() - self.python_session = None - if hasattr(self, 'robot_session') and (self.python_session is not None): - self.robot_session.destroy() - self.robot_session = None + if hasattr(self, '_lang_session') and (self._lang_session is not None): + self._lang_session.destroy() + self._lang_session = None # TODO: add any cleanups as features are added! def get_session_by_id(sid): -- cgit v1.2.1