Set timeout for xmlrpclib.ServerProxy

前端 未结 9 1603
轮回少年
轮回少年 2020-12-29 22:33

I am using xmlrpclib.ServerProxy to make RPC calls to a remote server. If there is not a network connection to the server it takes the default 10 seconds to return a socket.

相关标签:
9条回答
  • 2020-12-29 23:14

    I wanted a small, clean, but also explicit version, so based on all other answers here, this is what I came up with:

    import xmlrpclib
    
    
    class TimeoutTransport(xmlrpclib.Transport):
    
        def __init__(self, timeout, use_datetime=0):
            self.timeout = timeout
            # xmlrpclib uses old-style classes so we cannot use super()
            xmlrpclib.Transport.__init__(self, use_datetime)
    
        def make_connection(self, host):
            connection = xmlrpclib.Transport.make_connection(self, host)
            connection.timeout = self.timeout
            return connection
    
    
    class TimeoutServerProxy(xmlrpclib.ServerProxy):
    
        def __init__(self, uri, timeout=10, transport=None, encoding=None, verbose=0, allow_none=0, use_datetime=0):
            t = TimeoutTransport(timeout)
            xmlrpclib.ServerProxy.__init__(self, uri, t, encoding, verbose, allow_none, use_datetime)
    
    
    proxy = TimeoutServerProxy(some_url)
    

    I didn't realize at first xmlrpclib has old-style classes so I found it useful with a comment on that, otherwise everything should be pretty self-explanatory.

    I don't see why httplib.HTTP would have to be subclassed as well, if someone can enlighten me on this, please do. The above solution is tried and works.

    0 讨论(0)
  • 2020-12-29 23:23

    Here another smart and very pythonic solution using Python's with statement:

    import socket
    import xmlrpc.client
    
    class MyServerProxy:
        def __init__(self, url, timeout=None):
            self.__url = url
            self.__timeout = timeout
            self.__prevDefaultTimeout = None
    
        def __enter__(self):
            try:
                if self.__timeout:
                    self.__prevDefaultTimeout = socket.getdefaulttimeout()
                    socket.setdefaulttimeout(self.__timeout)
                proxy = xmlrpc.client.ServerProxy(self.__url, allow_none=True)
            except Exception as ex:
                raise Exception("Unable create XMLRPC-proxy for url '%s': %s" % (self.__url, ex))
            return proxy
        def __exit__(self, type, value, traceback):
            if self.__prevDefaultTimeout is None:
                socket.setdefaulttimeout(self.__prevDefaultTimeout)
    

    This class can be used like this:

    with MyServerProxy('http://1.2.3.4', 20) as proxy:
        proxy.dummy()
    
    0 讨论(0)
  • 2020-12-29 23:25

    The following example works with Python 2.7.4.

    import xmlrpclib
    from xmlrpclib import *
    import httplib
    
    def Server(url, *args, **kwargs):
        t = TimeoutTransport(kwargs.get('timeout', 20))
        if 'timeout' in kwargs:
           del kwargs['timeout']
        kwargs['transport'] = t
        server = xmlrpclib.Server(url, *args, **kwargs)
        return server
    
    TimeoutServerProxy = Server
    
    class TimeoutTransport(xmlrpclib.Transport):
    
        def __init__(self, timeout, use_datetime=0):
            self.timeout = timeout
            return xmlrpclib.Transport.__init__(self, use_datetime)
    
        def make_connection(self, host):
            conn = xmlrpclib.Transport.make_connection(self, host)
            conn.timeout = self.timeout
            return connrpclib.Server(url, *args, **kwargs)
    
    0 讨论(0)
提交回复
热议问题