def _thread(self,context,worker_id,import_class,pid,serverid,counters,methods,target,stype): """ Worker thread for zmqrpc server - binds to zmq socket (target) and works ZMQRPCServer import_class. Instantiated by work() threading Handles BSON in/out, zmq REP to zmq QUEUE or REQ """ socket = self.context.socket(zmq.REP) job_count = 0 if stype == LISTEN: socket.bind(target) else: socket.connect(target) nuclass = import_class() while True: sockin = socket.recv() message = BSON(sockin).decode() result = None fail = None tb = None method = str(message['method']) args = message.get('args',[]) # Convert kwargs from unicode strings to 8bit strings if method == '__threadstatus__': x = threading.current_thread() socket.send(BSON.encode({'runner':None,'traceback':None,'fail':False,'result':{'id':serverid+':'+str(pid)+':'+str(x.name),'alive':x.is_alive(),'job_count':counters.get(x.name,0),'last_method':methods.get(x.name,''),}})) else: try: kwargs = {} for (k,v) in message.get('kwargs',{}).iteritems(): kwargs[str(k)] = v job_count+=1 counters[threading.currentThread().name] = job_count methods[threading.currentThread().name] = method runner = {'job_count':job_count,'thread':threading.currentThread().name,'method':import_class.__name__+'.'+method,} # Find the method in the module, run it. try: if hasattr(nuclass,method): result = getattr(nuclass,method)(*args,**kwargs) fail = False else: fail = True tb = "NameError: name '"+method+"' is not defined in ZMQRPC class '"+import_class.__name__+"'" except: etype, evalue, etb = sys.exc_info() fail = True tb = "\n".join(traceback.format_exception(etype, evalue, etb)) socket.send(BSON.encode({'fail':fail,'result':result,'runner':runner,'traceback':tb})) except: etype, evalue, etb = sys.exc_info() fail = True tb = "\n".join(traceback.format_exception(etype, evalue, etb)) socket.send(BSON.encode({'fail':fail,'result':None,'runner':None,'traceback':tb}))
def _dorequest(self,msg,timeout=5): """ _dorequest: Set up a BSON string and send zmq REQ to ZMQRPC target """ # Set up bson message bson = BSON.encode(msg) # Send... try: self._pollout.poll(timeout=timeout*1000) # Poll for outbound send, then send self._zmqsocket.send(bson,flags=zmq.NOBLOCK) except: raise ZMQRPCError('Request failure') # Poll for inbound then rx try: for i in range(0,timeout*100): if len(self._pollin.poll(timeout=1)) > 0: break time.sleep(0.01) msg_in = self._zmqsocket.recv(flags=zmq.NOBLOCK) except: raise ZMQRPCError('Response timeout') if msg_in == None: raise ZMQRPCError('No response') result = BSON(msg_in).decode() self._lastrun = result.get('runner') return result
def call_server(self, rpc_controller, request, callback): method_name = request.method_name method_params = BSON(request.request_proto).decode() try: method = getattr(self._entity, method_name, None) params = method_params.get('param', []) method and method(*params) except: print 'call_server %s error.' % method_name
def _thread(self, context, worker_id, import_class, pid, serverid, counters, methods, target, stype, worker_args): """ Worker thread for zmqrpc server - binds to zmq socket (target) and works ZMQRPCServer import_class. Instantiated by work() threading Handles BSON in/out, zmq REP to zmq QUEUE or REQ """ socket = self.context.socket(zmq.REP) job_count = 0 if stype == LISTEN: socket.bind(target) else: socket.connect(target) if worker_args: nuclass = import_class(**worker_args) else: nuclass = import_class() while True: sockin = socket.recv() message = BSON(sockin).decode() result = None fail = None tb = None method = str(message['method']) args = message.get('args', []) if self.export and (not method in self.export): tb = "NameError: name '" + method + "' is not exported in ZMQRPC class '" + import_class.__name__ + "'" socket.send( BSON.encode({ 'fail': True, 'result': None, 'runner': None, 'traceback': tb })) return # Convert kwargs from unicode strings to 8bit strings if method == '__threadstatus__': x = threading.current_thread() socket.send( BSON.encode({ 'runner': None, 'traceback': None, 'fail': False, 'result': { 'id': serverid + ':' + str(pid) + ':' + str(x.name), 'alive': x.is_alive(), 'job_count': counters.get(x.name, 0), 'last_method': methods.get(x.name, ''), } })) else: try: kwargs = {} for (k, v) in message.get('kwargs', {}).iteritems(): kwargs[str(k)] = v job_count += 1 counters[threading.currentThread().name] = job_count methods[threading.currentThread().name] = method runner = { 'job_count': job_count, 'thread': threading.currentThread().name, 'method': import_class.__name__ + '.' + method, } # Find the method in the module, run it. try: if hasattr(nuclass, method): result = getattr(nuclass, method)(*args, **kwargs) fail = False else: fail = True tb = "NameError: name '" + method + "' is not defined in ZMQRPC class '" + import_class.__name__ + "'" except: etype, evalue, etb = sys.exc_info() fail = True tb = "\n".join( traceback.format_exception(etype, evalue, etb)) socket.send( BSON.encode({ 'fail': fail, 'result': result, 'runner': runner, 'traceback': tb })) except: etype, evalue, etb = sys.exc_info() fail = True tb = "\n".join( traceback.format_exception(etype, evalue, etb)) socket.send( BSON.encode({ 'fail': fail, 'result': None, 'runner': None, 'traceback': tb }))
def run(self): while self.__active: if self.__connected is None: # initializing time.sleep(1e-6) continue try: n = 4 head = six.b('') while n > 0: try: got = self.__sock.recv(n) except socket.error as e: if e.errno in ( 11, 35 ): # timeout or Resource temporarily unavailable self.__notify(-1, None) continue self.__notify(-1, e) raise _PleaseReconnect() if not got: self.__notify(-1, Error('Connection reset by peer')) raise _PleaseReconnect() n -= len(got) head += got assert (len(head) == 4) n0 = n = struct.unpack('<I', head)[0] if not n: continue body = six.b('') while n > 0: try: got = self.__sock.recv(n) except socket.error as e: if e.errno in ( 11, 35 ): # timeout or Resource temporarily unavailable self.__notify(-1, None) continue self.__notify(-1, e) raise _PleaseReconnect() if not got: self.__notify(-1, Error('Connection reset by peer')) raise _PleaseReconnect() n -= len(got) body += got if n0 == 1 and body == six.b('H'): # heartbeat try: self.__send() except socket.error as e: raise _PleaseReconnect() continue msg = BSON(body).decode() cached = msg.get('2') if cached is not None: msg['1'] = BSON(cached).decode()['1'] del msg['2'] self.__notify(msg['0'], msg) except _PleaseReconnect as e: if self.__auto_reconnect < 1: return if not self.__active: return time.sleep(self.__auto_reconnect) if not self.__active: return logging.info('OpenTick: trying reconnect') self.__close_socket() try: self.__connect() except socket.error as e: logging.error('OpenTick: failed to connect: ' + str(e)) continue