def __init__(self, socketpath, name, rpc_host): QuittableThread.__init__(self) self.socketpath = socketpath self.socket = None self.name = name self.rpc_host = rpc_host self.rpc_host.node_id = 0
def manage(self, peer_id, sock): if peer_id not in self.managed_sockets: self.managed_sockets[peer_id] = sock self.peers_by_socket[sock] = peer_id self.notify_peer(peer_id) if self.status_cb: cbthread = QuittableThread(target=self.status_cb, args=(peer_id, "manage")) cbthread.start()
def start(self): from mfp import log import subprocess arglist = [self.exec_file] + self.exec_args log.debug("RPCExecRemote: starting as ", arglist) self.process = subprocess.Popen([str(a) for a in arglist], bufsize=0, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) QuittableThread.start(self)
def finish(self): from mfp import log p = self.process self.process = None if p is not None: try: p.terminate() p.wait() except OSError as e: pass self.quit_req = True QuittableThread.finish(self)
def main(): socketpath = sys.argv[1] remote_host = RPCHost() remote_host.publish(WrappedClass) remote_host.publish(ReverseClass) remote_host.start() remote_conn = RPCRemote(socketpath, "RPCTests_remote", remote_host) remote_conn.connect() try: QuittableThread.wait_for_all() except Exception, e: print "wait_for_all caught error"
def unmanage(self, peer_id): if peer_id in self.managed_sockets: # remove this peer as a publisher for any classes for clsname, cls in RPCWrapper.rpctype.items(): if peer_id in cls.publishers: cls.publishers.remove(peer_id) oldsock = self.managed_sockets[peer_id] del self.managed_sockets[peer_id] del self.peers_by_socket[oldsock] if oldsock.fileno() in self.fdsockets: del self.fdsockets[oldsock.fileno()] if self.status_cb: cbthread = QuittableThread(target=self.status_cb, args=(peer_id, "unmanage")) cbthread.start()
def __init__(self, exec_file, *args, **kwargs): from mfp import log QuittableThread.__init__(self) self.exec_file = exec_file self.exec_args = list(args) self.process = None if "log_module" in kwargs: self.log_module = kwargs["log_module"] else: self.log_module = log.log_module if kwargs.get("log_raw"): self.log_raw = True else: self.log_raw = False
def __init__(self, exec_file, *args, **kwargs): from mfp import log QuittableThread.__init__(self) self.exec_file = exec_file self.exec_args = list(args) self.process = None if kwargs.has_key("log_module"): self.log_module = kwargs["log_module"] else: self.log_module = log.log_module if kwargs.get("log_raw"): self.log_raw = True else: self.log_raw = False
def __init__(self, status_cb=None): QuittableThread.__init__(self) # FIXME -- one lock/condition per RPCHost means lots of # unneeded waking up if lots of requests are queued self.lock = threading.Lock() self.condition = threading.Condition(self.lock) self.pending = {} self.node_id = None self.fdsockets = {} self.status_cb = status_cb self.served_classes = {} self.managed_sockets = {} self.peers_by_socket = {} self.read_workers = WorkerPool(self.dispatch_rpcdata)
def handle_request(self, req, peer_id): from datetime import datetime method = req.method rpcdata = req.params rpcid = rpcdata.get('rpcid') args = rpcdata.get('args') or [] kwargs = rpcdata.get('kwargs') or {} req.state = Request.RESPONSE_DONE req.diagnostic['local_call_started'] = str(datetime.now()) if method == 'create': factory = RPCWrapper.rpctype.get(rpcdata.get('type')) if factory: obj = factory(*args, **kwargs) req.result = (True, obj.rpcid) else: req.result = (RPCWrapper.NO_CLASS, None) elif method == 'delete': del RPCWrapper.objects[rpcid] req.result = (True, None) elif method == 'call': obj = RPCWrapper.rpcobj.get(rpcid) try: retval = obj.call_locally(rpcdata) req.result = (RPCWrapper.METHOD_OK, retval) except RPCWrapper.MethodNotFound as e: req.result = (RPCWrapper.NO_METHOD, None) except RPCWrapper.MethodFailed as e: req.result = (RPCWrapper.METHOD_FAILED, e.traceback) except Exception as e: import traceback einfo = ("Method call failed rpcid=%s node=%s\nobj=%s data=%s\n" % (rpcid, peer_id, obj, rpcdata)) req.result = (RPCWrapper.METHOD_FAILED, einfo + traceback.format_exc()) elif method == 'publish': for clsname in req.params.get("classes"): cls = RPCWrapper.rpctype.get(clsname) if cls is not None: cls.publishers.append(peer_id) if self.status_cb: cbthread = QuittableThread(target=self.status_cb, args=(peer_id, "publish", req.params.get("classes"), req.params.get("pubdata"))) cbthread.start() req.result = (True, None) elif method == "ready": req.result = (True, peer_id) elif method == "exit_request": if not self.join_req: self.finish() req.request_id = None elif method == "exit_notify": self.unmanage(peer_id) # FIXME: exit_notify should cause patches to be closed req.request_id = None elif method == "node_status": pass else: print("rpc_wrapper: WARNING: no handler for method '%s'" % method) print("call data:", rpcid, method, rpcdata) req.method = None req.params = None req.diagnostic['local_call_complete'] = str(datetime.now())
req.result = (RPCWrapper.METHOD_FAILED, e.traceback) except Exception, e: import traceback einfo = ("Method call failed rpcid=%s node=%s\nobj=%s data=%s\n" % (rpcid, peer_id, obj, rpcdata)) req.result = (RPCWrapper.METHOD_FAILED, einfo + traceback.format_exc()) elif method == 'publish': for clsname in req.params.get("classes"): cls = RPCWrapper.rpctype.get(clsname) if cls is not None: cls.publishers.append(peer_id) if self.status_cb: cbthread = QuittableThread(target=self.status_cb, args=(peer_id, "publish", req.params.get("classes"))) cbthread.start() req.result = (True, None) elif method == "ready": req.result = (True, peer_id) elif method == "exit_request": if not self.join_req: self.finish() req.request_id = None elif method == "exit_notify": self.unmanage(peer_id) # FIXME: exit_notify should cause patches to be closed
self.process.wait() def finish(self): from mfp import log p = self.process self.process = None if p is not None: try: p.terminate() p.wait() except OSError, e: log.warning( "RPCExecRemote: caught error in terminate(), continuing") self.quit_req = True QuittableThread.finish(self) def alive(self): if not self.process: return False else: return not self.process.poll() class RPCMultiRemote(object): ''' RPCMultiRemote -- launch a process with multiprocessing which will connect back to this process ''' def __init__(self, thunk, *args): self.thunk = thunk
self.process.terminate() self.process.wait() def finish(self): from mfp import log p = self.process self.process = None if p is not None: try: p.terminate() p.wait() except OSError, e: pass self.quit_req = True QuittableThread.finish(self) def alive(self): if not self.process: return False else: return not self.process.poll() class RPCMultiRemote (object): ''' RPCMultiRemote -- launch a process with multiprocessing which will connect back to this process ''' def __init__(self, thunk, *args): self.thunk = thunk self.args = args
def handle_request(self, req, peer_id): from datetime import datetime method = req.method rpcdata = req.params rpcid = rpcdata.get('rpcid') args = rpcdata.get('args') or [] kwargs = rpcdata.get('kwargs') or {} req.state = Request.RESPONSE_DONE req.diagnostic['local_call_started'] = str(datetime.now()) if method == 'create': factory = RPCWrapper.rpctype.get(rpcdata.get('type')) if factory: obj = factory(*args, **kwargs) req.result = (True, obj.rpcid) else: req.result = (RPCWrapper.NO_CLASS, None) elif method == 'delete': del RPCWrapper.objects[rpcid] req.result = (True, None) elif method == 'call': obj = RPCWrapper.rpcobj.get(rpcid) try: retval = obj.call_locally(rpcdata) req.result = (RPCWrapper.METHOD_OK, retval) except RPCWrapper.MethodNotFound as e: req.result = (RPCWrapper.NO_METHOD, None) except RPCWrapper.MethodFailed as e: req.result = (RPCWrapper.METHOD_FAILED, e.traceback) except Exception as e: import traceback einfo = ( "Method call failed rpcid=%s node=%s\nobj=%s data=%s\n" % (rpcid, peer_id, obj, rpcdata)) req.result = (RPCWrapper.METHOD_FAILED, einfo + traceback.format_exc()) elif method == 'publish': for clsname in req.params.get("classes"): cls = RPCWrapper.rpctype.get(clsname) if cls is not None: cls.publishers.append(peer_id) if self.status_cb: cbthread = QuittableThread(target=self.status_cb, args=(peer_id, "publish", req.params.get("classes"), req.params.get("pubdata"))) cbthread.start() req.result = (True, None) elif method == "ready": req.result = (True, peer_id) elif method == "exit_request": if not self.join_req: self.finish() req.request_id = None elif method == "exit_notify": self.unmanage(peer_id) # FIXME: exit_notify should cause patches to be closed req.request_id = None elif method == "node_status": pass else: print("rpc_wrapper: WARNING: no handler for method '%s'" % method) print("call data:", rpcid, method, rpcdata) req.method = None req.params = None req.diagnostic['local_call_complete'] = str(datetime.now())