Ejemplo n.º 1
0
    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}))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
    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
                        }))
Ejemplo n.º 5
0
 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