From 8cd70975854ddefaf9dadbade1559059ad781f3c Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Fri, 28 Aug 2015 11:47:53 +0200 Subject: Add Python session support --- server/python_session.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ server/user_session.py | 11 +++++++++++ 2 files changed, 58 insertions(+) create mode 100644 server/python_session.py diff --git a/server/python_session.py b/server/python_session.py new file mode 100644 index 0000000..7a5d22a --- /dev/null +++ b/server/python_session.py @@ -0,0 +1,47 @@ +# coding=utf-8 + +import threading +import python.engine + +__all__ = ['PythonSession'] + +class PythonSession(object): + """Abstracts a Python session. + Only public methods are available to the outside world due to the use of multiprocessing managers. + Therefore prefix any private methods with an underscore (_). + No properties are accessible; use getters and setters instead. + Values are passed by value instead of by reference (deep copy!). + """ + def __init__(self): + self._access_lock = threading.Lock() + self._interpreter = None + + def create(self): + with self._access_lock: + if not self._interpreter: + self._interpreter = python.engine.create() + + def pull(self): + with self._access_lock: + if self._interpreter is None: + return 'Python is not running' + return python.engine.pull(self._interpreter) + + def push(self, stdin): + with self._access_lock: + if self._interpreter is not None: + python.engine.push(self._interpreter, stdin) + + def destroy(self): + with self._access_lock: + if self._interpreter is not None: + python.engine.destroy(self._interpreter) + self._interpreter = None + + def __del__(self): + if hasattr(self, '_interpreter') and self._interpreter is not None: + python.engine.destroy(self._interpreter) + self._interpreter = None + + def test(self, user_id, problem_id, program): + return ['Python testing is not implemented yet'] diff --git a/server/user_session.py b/server/user_session.py index c9d21b4..0abc421 100644 --- a/server/user_session.py +++ b/server/user_session.py @@ -6,6 +6,7 @@ import hashlib import base64 import random from . import prolog_session +from . import python_session from . import problems import db from errors.session import NoSuchSession, AuthenticationFailed @@ -30,6 +31,7 @@ class UserSession(object): self.uid = uid self.username = username self.prolog_session = None + self.python_session = None def destroy(self): """Destroys the session.""" @@ -39,6 +41,9 @@ class UserSession(object): 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.end() + self.python_session = None # TODO: add any cleanups as features are added! def get_sid(self): @@ -53,6 +58,12 @@ class UserSession(object): self.prolog_session = prolog_session.PrologSession() # lazy init return self.prolog_session + def get_python(self): + with self._access_lock: + if self.python_session is None: + self.python_session = python_session.PythonSession() # lazy init + return self.python_session + def get_problem_data(self, language, problem_group, problem): mod = problems.load_problem(language, problem_group, problem, 'en') conn = db.get_connection() -- cgit v1.2.1