예제 #1
0
    def __init__(self, pipe, object_class, factory, id, _event_loop=None ):
        self.factory = factory
        self.factory_id = id
        self.pipe = pipe
        self.object_class = object_class
        signal_names = [name for name in dir(self.object_class) if name in self.object_class.__dict__ and type(self.object_class.__dict__[name]) == signal]
        instance_method_type = type(self.__init__)
        function_type = type(lambda x: x)
        method_names = [name for name in dir(self.object_class) if name in self.object_class.__dict__ and type(self.object_class.__dict__[name]) == function_type ]
        for name in signal_names:
            self.__setattr__(name, signal())
        for name in method_names:
            if name.startswith("_"):
                continue
            self.__setattr__(name, self._create_method(name))
            self.__setattr__(name + '_result', signal())
        if '_event_loop' is None:
            self.event_loop = ThreadedEventLoop()
        else:
            self.event_loop = _event_loop

        self.event_loop.register_hook(self.event_loop_hook)
예제 #2
0
class local_proxy(object):
    def _create_method(self, name ):
        def method(*args, **kwargs):
            return self._dispatch_method(name, *args, **kwargs)
        return method

    def __init__(self, pipe, object_class, factory, id, _event_loop=None ):
        self.factory = factory
        self.factory_id = id
        self.pipe = pipe
        self.object_class = object_class
        signal_names = [name for name in dir(self.object_class) if name in self.object_class.__dict__ and type(self.object_class.__dict__[name]) == signal]
        instance_method_type = type(self.__init__)
        function_type = type(lambda x: x)
        method_names = [name for name in dir(self.object_class) if name in self.object_class.__dict__ and type(self.object_class.__dict__[name]) == function_type ]
        for name in signal_names:
            self.__setattr__(name, signal())
        for name in method_names:
            if name.startswith("_"):
                continue
            self.__setattr__(name, self._create_method(name))
            self.__setattr__(name + '_result', signal())
        if '_event_loop' is None:
            self.event_loop = ThreadedEventLoop()
        else:
            self.event_loop = _event_loop

        self.event_loop.register_hook(self.event_loop_hook)

    def _dispatch_method(self, method_name, *args, **kwargs):
        if '_priority' in kwargs:
            p = kwargs['_priority']
            del kwargs['_priority']
        else:
            p = rpc.PRIORITY_NORMAL
        if '_async' in kwargs:
            async = kwargs['_async']
            del kwargs['_async']
        else:
            async = True
        if '_timeout' in kwargs:
            timeout = kwargs['_timeout']
            del kwargs['_timeout']
            async = False
            if '_default' in kwargs:
                default_ret = kwargs['_default']
                del kwargs['_default']
            else:
                default_ret = None
        else:
            timeout = None
        logger.debug(msg("Timeout == ", timeout))
        command = rpc(method_name, *args, **kwargs)
        command.priority = p
        logger.debug(msg("Dispatching rpc for ", method_name))
        self.pipe.send(command)
        time_start = time()
        if timeout is not None:
            logger.debug(msg("Time start == ", time_start))
        while not async:
            ret = self._process_command(block=False, return_response_to=command.message_id)
            if ret is not None:
                return ret
            if timeout is not None and time() - time_start > timeout:
                return default_ret
            if time() % 10 == 0:
                logger.debug(msg(self, "Time:", time()))

    def _process_command(self, block=False, return_response_to=None):
        if not block and not self.pipe.poll():
            return
        try:
            command = self.pipe.recv()
        except Exception, e:
            logger.error(msg("Error when receiving command:", e))
            return None
        if command.rpc_type == rpc.OBJECT_MESSAGE:
            signal = self.__getattribute__(command.message_name)
            signal.emit(*command.args, **command.kwargs)
        elif command.rpc_type == rpc.OBJECT_MESSAGE_RESPONSE:
            if return_response_to == command.response_to:
                return command.response_data
            else:
                signal = self.__getattribute__(command.message_name + '_result')
                signal.emit(command.response_data)
        elif command.rpc_type == rpc.ERROR_MESSAGE:
            if return_response_to == command.response_to:
                if command.error_typ == 'exception':
                    raise command.exception
                else:
                    raise Exception("Error in remote call: " + command.error_description)