设置xmlrpclib.ServerProxy的超时

ash*_*her 21 python xml-rpc

我正在使用xmlrpclib.ServerProxy对远程服务器进行RPC调用.如果没有到服务器的网络连接,则需要默认的10秒钟才能将socket.gaierror返回给我的程序.

在没有网络连接的情况下进行开发或者远程服务器关闭时,这很烦人.有没有办法更新我的ServerProxy对象上的超时?

我看不到一个明确的方法来访问套接字来更新它.

aza*_*ias 19

更直接的解决方案是: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
Run Code Online (Sandbox Code Playgroud)


小智 16

干净的非全球版本.

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()
Run Code Online (Sandbox Code Playgroud)

  • 在Python 2.7上不适合我.当我进行RPC调用时,我得到错误`AttributeError:TimeoutHTTP实例没有属性'getresponse' (5认同)

Tro*_*ell 5

我已经看了几种方法来解决这个问题,到目前为止,最优雅的方法在这里描述:https: //seattle.cs.washington.edu/browser/seattle/trunk/demokit/timeout_xmlrpclib.py?ev = 692

这项技术最初是在这里提出的,但这个链接已经死了:http: //blog.bjola.ca/2007/08/using-timeout-with-xmlrpclib.html

这适用于Python 2.5和2.6.新链接声称也可以使用Python 3.0.


Mar*_*son 5

我想要一个小而干净但也明确的版本,所以根据这里的所有其他答案,这就是我想出的:

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)
Run Code Online (Sandbox Code Playgroud)

起初我没有意识到xmlrpclib有旧式的类,所以我发现它很有用,对此发表评论,否则一切都应该是不言自明的。

我不明白为什么httplib.HTTP还必须被子类化,如果有人可以启发我,请这样做。上述解决方案已尝试并有效。


mon*_*kut 1

这是来自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
Run Code Online (Sandbox Code Playgroud)