Set timeout for xmlrpclib.ServerProxy

前端 未结 9 1602
轮回少年
轮回少年 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:00

    Here is a verbatim copy from http://code.activestate.com/recipes/473878/

    def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
        import threading
        class InterruptableThread(threading.Thread):
            def __init__(self):
            threading.Thread.__init__(self)
            self.result = None
    
            def run(self):
                try:
                    self.result = func(*args, **kwargs)
                except:
                    self.result = default
    
        it = InterruptableThread()
        it.start()
        it.join(timeout_duration)
        if it.isAlive():
            return default
        else:
            return it.result
    
    0 讨论(0)
  • 2020-12-29 23:03

    An more straightforward solution is at: http://www.devpicayune.com/entry/200609191448

    import xmlrpclib 
    import socket
    
    x = xmlrpclib.ServerProxy('http:1.2.3.4')  
    socket.setdefaulttimeout(10)        #set the timeout to 10 seconds 
    x.func_name(args)                   #times out after 10 seconds
    socket.setdefaulttimeout(None)      #sets the default back
    
    0 讨论(0)
  • 2020-12-29 23:08

    Based on the one from antonylesuisse, a working version (on python >= 2.6).

    # -*- coding: utf8 -*-
    import xmlrpclib
    import httplib
    import socket
    
    class TimeoutHTTP(httplib.HTTP):
       def __init__(self, host='', port=None, strict=None,
                    timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
            if port == 0:
                port = None
            self._setup(self._connection_class(host, port, strict, timeout))
    
    class TimeoutTransport(xmlrpclib.Transport):
        def __init__(self, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *args, **kwargs):
            xmlrpclib.Transport.__init__(self, *args, **kwargs)
            self.timeout = timeout
    
        def make_connection(self, host):
            host, extra_headers, x509 = self.get_host_info(host)
            conn = TimeoutHTTP(host, timeout=self.timeout)
            return conn
    
    class TimeoutServerProxy(xmlrpclib.ServerProxy):
        def __init__(self, uri, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
                     *args, **kwargs):
            kwargs['transport'] = TimeoutTransport(timeout=timeout,
                                        use_datetime=kwargs.get('use_datetime', 0))
            xmlrpclib.ServerProxy.__init__(self, uri, *args, **kwargs)
    
    0 讨论(0)
  • 2020-12-29 23:09

    Here is code that works on Python 2.7 (probably for other 2.x versions of Python) without raising AttributeError, instance has no attribute 'getresponse'.

    
    class TimeoutHTTPConnection(httplib.HTTPConnection):
        def connect(self):
            httplib.HTTPConnection.connect(self)
            self.sock.settimeout(self.timeout)
    
    class TimeoutHTTP(httplib.HTTP):
        _connection_class = TimeoutHTTPConnection
    
        def set_timeout(self, timeout):
            self._conn.timeout = timeout
    
    class TimeoutTransport(xmlrpclib.Transport):
        def __init__(self, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *args, **kwargs):
            xmlrpclib.Transport.__init__(self, *args, **kwargs)
            self.timeout = timeout
    
        def make_connection(self, host):
            if self._connection and host == self._connection[0]:
                return self._connection[1]
    
            chost, self._extra_headers, x509 = self.get_host_info(host)
            self._connection = host, httplib.HTTPConnection(chost)
            return self._connection[1]
    
    
    transport = TimeoutTransport(timeout=timeout)
    xmlrpclib.ServerProxy.__init__(self, uri, transport=transport, allow_none=True)
    
    0 讨论(0)
  • 2020-12-29 23:12

    Based on the one from antonylesuisse, but works on Python 2.7.5, resolving the problem:AttributeError: TimeoutHTTP instance has no attribute 'getresponse'

    class TimeoutHTTP(httplib.HTTP):
        def __init__(self, host='', port=None, strict=None,
                    timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
            if port == 0:
                port = None
            self._setup(self._connection_class(host, port, strict, timeout))
    
        def getresponse(self, *args, **kw):
            return self._conn.getresponse(*args, **kw)
    
    class TimeoutTransport(xmlrpclib.Transport):
        def __init__(self,  timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *l, **kw):
            xmlrpclib.Transport.__init__(self, *l, **kw)
            self.timeout=timeout
    
        def make_connection(self, host):
            host, extra_headers, x509 = self.get_host_info(host)
            conn = TimeoutHTTP(host, timeout=self.timeout)
            return conn
    
    class TimeoutServerProxy(xmlrpclib.ServerProxy):
        def __init__(self, uri, timeout= socket._GLOBAL_DEFAULT_TIMEOUT, *l, **kw):
            kw['transport']=TimeoutTransport(timeout=timeout, use_datetime=kw.get('use_datetime',0))
            xmlrpclib.ServerProxy.__init__(self, uri, *l, **kw)
    
    proxy = TimeoutServerProxy('http://127.0.0.1:1989', timeout=30)
    print proxy.test_connection()
    
    0 讨论(0)
  • 2020-12-29 23:13

    clean non global version.

    import xmlrpclib
    import httplib
    
    
    class TimeoutHTTPConnection(httplib.HTTPConnection):
        def connect(self):
            httplib.HTTPConnection.connect(self)
            self.sock.settimeout(self.timeout)
    
    
    class TimeoutHTTP(httplib.HTTP):
        _connection_class = TimeoutHTTPConnection
    
        def set_timeout(self, timeout):
            self._conn.timeout = timeout
    
    
    class TimeoutTransport(xmlrpclib.Transport):
        def __init__(self, timeout=10, *l, **kw):
            xmlrpclib.Transport.__init__(self, *l, **kw)
            self.timeout = timeout
    
        def make_connection(self, host):
            conn = TimeoutHTTP(host)
            conn.set_timeout(self.timeout)
            return conn
    
    
    class TimeoutServerProxy(xmlrpclib.ServerProxy):
        def __init__(self, uri, timeout=10, *l, **kw):
            kw['transport'] = TimeoutTransport(
                timeout=timeout, use_datetime=kw.get('use_datetime', 0))
            xmlrpclib.ServerProxy.__init__(self, uri, *l, **kw)
    
    
    if __name__ == "__main__":
        s = TimeoutServerProxy('http://127.0.0.1:9090', timeout=2)
        s.dummy()
    
    0 讨论(0)
提交回复
热议问题