summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@araneo.org>2015-09-03 17:07:27 +0200
committerTimotej Lazar <timotej.lazar@araneo.org>2015-09-03 17:07:27 +0200
commit401bef2dcb434c23eb783131fb36d952043b9f31 (patch)
tree589a317e0c4d71318bb6b1f37ef465a4296973f5 /server
parent3a17e047b53760c787c050432372170e745a318e (diff)
Use multiprocessing.managers for the Python runner
Diffstat (limited to 'server')
-rw-r--r--server/python_session.py28
-rw-r--r--server/user_session.py3
2 files changed, 24 insertions, 7 deletions
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):