def start(self, system): self.defer_ready = defer.Deferred() if system == 'python': from knoboo.kernel.engine.python import runtime elif system == 'sage': from knoboo.kernel.engine.sage import runtime if self.user_pool: try: self.uid = self.user_pool.pop() self.gid = self.user_pool.gid except IndexError: return 'Max users exceeded. Try again later.' else: self.uid = self.config['engines-uid'] self.gid = self.uid process_setup = runtime.ProcessSetup(self.config, self.id, self.uid, self.gid) self.control = EngineProcessControl() self.control.buildProcess(process_setup) self.control.manager = self self.procman.addProcess(self.control) return self.defer_ready
class EngineManager(EngineObject): def __init__(self, id, mind, config, procman, user_pool=False): """need to add system spec in args """ self.id = id self.mind = mind self.config = config self.procman = procman self.user_pool = user_pool self.interrupted = False self.client = None #d = self.mind.callRemote('getSystem') #d.addCallback(self.start) #self.start() def start(self, system): self.defer_ready = defer.Deferred() if system == 'python': from knoboo.kernel.engine.python import runtime elif system == 'sage': from knoboo.kernel.engine.sage import runtime if self.user_pool: try: self.uid = self.user_pool.pop() self.gid = self.user_pool.gid except IndexError: return 'Max users exceeded. Try again later.' else: self.uid = self.config['engines-uid'] self.gid = self.uid process_setup = runtime.ProcessSetup(self.config, self.id, self.uid, self.gid) self.control = EngineProcessControl() self.control.buildProcess(process_setup) self.control.manager = self self.procman.addProcess(self.control) return self.defer_ready def stop(self): self.procman.removeProcess(self.id) def processStarted(self, port): url = 'http://localhost:' + port self.client = RPCClient(url) d = self.client.callRemote('hello') d.addCallback(self._engine_ready) return d def processStopped(self): """if the process stops for any reason, the process protocol will call this function. """ if self.user_pool: self.user_pool.append(self.uid) def _engine_ready(self, res): self.client.callRemote('interpreter_go') self.defer_ready.callback('ok') def interrupt(self): di = self.control.interrupt() d = self.call('cancel_interrupt') d.addCallback(self._cancel_interrupt_callback) d.addErrback(self._cancel_interrupt_errback) self.set_interrupted() return d def set_interrupted(self): self.interrupted = True def cancel_interrupt(self): self.interrupted = False self.control.cancel_interrupt() def _cancel_interrupt_callback(self, result): #self.control.cancel_interrupt() return 'ok' def _cancel_interrupt_errback(self, reason): return 'fail' def call(self, method, *args): """wrapper around callRemote """ d = self.client.callRemote(method, *args) d.addCallback(self.clientCallback) d.addErrback(self.clientErrback) return d def clientCallback(self, result): """First callback after engine returns """ if self.interrupted: self.cancel_interrupt() return self.output_type(result) def clientErrback(self, res): return res def output_type(self, output): """determine what the output is so eventually the browser can properly display it. """ image_preface = "__imagefile__" out = output['out'] if image_preface in out: image_path = out[13:] image_path = image_path.strip('\n') f = file(image_path, 'r') image = f.read() f.close() os.remove(image_path) image_name = os.path.basename(image_path) web_path = os.path.join('/images', image_name) web_path = '__image__' + web_path output['out'] = web_path d = self.mind.callRemote('writeImage', image, image_name) d.addCallback(self._output_type_callback, output) return d return output def _output_type_callback(self, result, output): return output