1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
import exceptions, os
from pypy.tool import slaveproc
class IsolateException(Exception):
pass
class IsolateInvoker(object):
# to have a nice repr
def __init__(self, isolate, name):
self.isolate = isolate
self.name = name
def __call__(self, *args):
return self.isolate._invoke(self.name, args)
def __repr__(self):
return "<invoker for %r . %r>" % (self.isolate.module, self.name)
def close_isolate(self):
self.isolate._close()
class Isolate(object):
"""
Isolate lets load a module in a different process,
and support invoking functions from it passing and
returning simple values
module: a dotted module name or a tuple (directory, module-name)
"""
_closed = False
def __init__(self, module):
self.module = module
self.slave = slaveproc.SlaveProcess(os.path.join(os.path.dirname(__file__),
'isolate_slave.py'))
res = self.slave.cmd(('load', module))
assert res == 'loaded'
def __getattr__(self, name):
return IsolateInvoker(self, name)
def _invoke(self, func, args):
status, value = self.slave.cmd(('invoke', (func, args)))
print 'OK'
if status == 'ok':
return value
else:
exc_type_module, exc_type_name = value
if exc_type_module == 'exceptions':
raise getattr(exceptions, exc_type_name)
else:
raise IsolateException("%s.%s" % value)
def _close(self):
if not self._closed:
self.slave.close()
self._closed = True
def __del__(self):
self._close()
def close_isolate(isolate):
assert isinstance(isolate, Isolate)
isolate._close()
|