summaryrefslogtreecommitdiff
path: root/server/python_session.py
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/python_session.py
parent3a17e047b53760c787c050432372170e745a318e (diff)
Use multiprocessing.managers for the Python runner
Diffstat (limited to 'server/python_session.py')
-rw-r--r--server/python_session.py28
1 files changed, 21 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):