示例#1
0
class SingleMindedProxy(object):
    MAX_CALL_LENGTH = 600.0 # The maximum amount of seconds to wait for a remote call to finish.
    
    """A proxy handling a connection to an instance of SingleMindedRPC"""
    def __init__(self, address=('localhost', 3344)):
        super(SingleMindedProxy, self).__init__()
        
        # Store member variables.
        self.__address = address

        # Create a socket and connect to the server.
        self.__sock = TimedSocket()
        self.__connected = False
        self.__connect()     
        self.__lock = allocate_lock()       
    
    def __nonzero__(self):
        return True
    
    def __getattr__(self, attrname):
        """
        Forwards any unknown attribute requests to the function that 
        makes RPC calls to the server.
        @type attrname: str
        @param attrname: The attribute to search for. In this case it must 
        be the name of a remote method on the RPC server. 
        """
        if attrname == '':
            return self
        else:
            return partial(self.make_rpc_call, attrname)
    
    def set_address(self, address):
        """
        Set the address of the RPC server.
        @type address: tuple
        @param address: The address where the SingleMindedRPC server is
        listening.
        """
        self.__address = address
    
    def __connect(self):
        """Connects to an instance of SingleMindedRPC."""
        try:
            self.__sock.connect(self.__address)
        except Exception, excep:
            raise CommunicationError('Error connecting to RPC server.', excep)
        self.__connected = True
示例#2
0
    def __init__(self, address=('localhost', 3344)):
        super(SingleMindedProxy, self).__init__()
        
        # Store member variables.
        self.__address = address

        # Create a socket and connect to the server.
        self.__sock = TimedSocket()
        self.__connected = False
        self.__connect()     
        self.__lock = allocate_lock()       
示例#3
0
 def __init__(self, address=('', 0)):
     """
     Constructor.
     @type address: tuple
     @param address: The address that the RPC server should listen on for
     incoming connection requests. 
     """
     # Initialize super class.
     super(SingleMindedRPC, self).__init__()
     
     # Create server socket listening for incoming requests.
     self.__server_sock = TimedSocket()
     self.__server_sock.bind(address)
     self.__server_sock.listen(5)
     
     # Set member variables.
     self.__functions = {}
     self.__shutdown = False
     self.__shutdown_signal = allocate_lock()
示例#4
0
class SingleMindedRPC(Thread):
    """The single-minded RPC server."""
    
    def __init__(self, address=('', 0)):
        """
        Constructor.
        @type address: tuple
        @param address: The address that the RPC server should listen on for
        incoming connection requests. 
        """
        # Initialize super class.
        super(SingleMindedRPC, self).__init__()
        
        # Create server socket listening for incoming requests.
        self.__server_sock = TimedSocket()
        self.__server_sock.bind(address)
        self.__server_sock.listen(5)
        
        # Set member variables.
        self.__functions = {}
        self.__shutdown = False
        self.__shutdown_signal = allocate_lock()

    def shutdown(self):
        return self.__shutdown

    def get_function(self, function_name):
        if self.__functions.has_key(function_name):
            return self.__functions[function_name]
        else:
            return None
    
    def remove_connection(self, connection):
        with self.__connections_lock:
            self.__connections.remove(connection)
    
    def add_connection(self, connection):
        with self.__connections_lock:
            self.__connections.append(connection)
        
    def get_address(self):
        return self.__server_sock.addr
        
    def debug_print(self):
        print 'Registered functions:', self.__functions

    def register_function(self, rpc_function, rpc_name=''):
        """
        Registers a new function with the RPC server. This function may 
        afterwards be called by remote clients.
        @type rpc_function: function
        @param rpc_function: The function to register.
        @type rpc_name: str
        @param rpc_name: An (optional) name to use for the function. If this is not
        given the functions original name is used.
        """
        # Do simple type-checking.
        if not type(rpc_function) in (FunctionType, MethodType) or type(rpc_name) != StringType:
            raise TypeError('Arguments of invalid type given.')
        
        # Check that the name is not already taken.
        if rpc_name == '':
            rpc_name = rpc_function.__name__
        if self.__functions.has_key(rpc_name):
            raise SMRPCError('The function name %s is already taken.'%rpc_name)
        
        # Add the function to the list.
        self.__functions[rpc_name] = rpc_function
            
    def stop(self, block=False):
        """Stop the RPC server thread.
        @type block: bool
        @param block: Whether or not the call should block until the service is 
        closed down properly.
        """
        self.__shutdown = True
        
        if block:
            self.__shutdown_signal.acquire()
            self.__shutdown_signal.release()

    def teardown(self):
        """
        Close down the RPC server completely. This closes the server socket
        making the SingleMindedRPC object unusable.
        """
        self.__server_sock.close()

    def run(self):
        """
        Main thread function.
        """
        self.__shutdown_signal.acquire()
        self.__shutdown = False
        
        while not self.__shutdown:
        # Wait for an incoming connection attempt.
            try:
                # Accept an incoming connection attempt.
                new_sock = self.__server_sock.accept()
                # Create a new worker thread and start it.
                connection = SingleMindedWorker(new_sock, self)
                connection.start()
            except Timeout:
                continue
                    
        # Reset the shutdown indicator.
        self.__shutdown_signal.release()

    def __wait_for_connection(self):
        """Waits for a connection to arrive on the server socket."""
        # Wait for an incoming connection attempt.
        try:
            connection = self.__server_sock.accept()
        except Timeout:
            return

        # A connection has been established.
        self.__connected = True
        self.__client_sock = connection