From 401bef2dcb434c23eb783131fb36d952043b9f31 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Thu, 3 Sep 2015 17:07:27 +0200 Subject: Use multiprocessing.managers for the Python runner --- server/python_session.py | 28 +++++++++++++++++++++------- server/user_session.py | 3 +++ 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'server') diff --git a/server/python_session.py b/server/python_session.py index 641c8ee..648a901 100644 --- a/server/python_session.py +++ b/server/python_session.py @@ -1,7 +1,7 @@ # coding=utf-8 +import multiprocessing.managers import threading -import python.engine from db.models import Problem from . import problems @@ -18,31 +18,45 @@ class PythonSession(object): self._access_lock = threading.Lock() self._interpreter = None + # Proxy for calling the Python runner. We use a separate connection for + # each session so the runner can be restarted without affecting the + # server. + _m = multiprocessing.managers.BaseManager(address=('localhost', 3031), + authkey=b'c0d3q3y-python') + _m.register('Python') + _m.connect() + self._python = _m.Python() + + def run(self, code=None, inputs=None, timeout=1.0): + with self._access_lock: + return self._python.run(code, inputs, timeout) + def create(self): with self._access_lock: - if not self._interpreter: - self._interpreter = python.engine.create() + if self._interpreter is None: + self._interpreter = self._python.create() def pull(self): with self._access_lock: if self._interpreter is None: return 'Python is not running' - return python.engine.pull(self._interpreter) + return self._python.pull(self._interpreter) def push(self, stdin): with self._access_lock: if self._interpreter is not None: - python.engine.push(self._interpreter, stdin) + self._python.push(self._interpreter, stdin) def destroy(self): with self._access_lock: if self._interpreter is not None: - python.engine.destroy(self._interpreter) + self._python.destroy(self._interpreter) self._interpreter = None def __del__(self): + # no locking needed if GC is removing us, as there cannot be any concurrent access by definition if hasattr(self, '_interpreter') and self._interpreter is not None: - python.engine.destroy(self._interpreter) + self._python.destroy(self._interpreter) self._interpreter = None def hint(self, user_id, problem_id, program): diff --git a/server/user_session.py b/server/user_session.py index 60289dc..f21102c 100644 --- a/server/user_session.py +++ b/server/user_session.py @@ -133,6 +133,9 @@ class UserSession(object): 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 # TODO: add any cleanups as features are added! def get_session_by_id(sid): -- cgit v1.2.1