python 为 xmlrpclib.ServerProxy 设置超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/372365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set timeout for xmlrpclib.ServerProxy
提问by ashchristopher
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.gaierror to my program.
我正在使用 xmlrpclib.ServerProxy 对远程服务器进行 RPC 调用。如果没有到服务器的网络连接,它需要默认 10 秒将 socket.gaierror 返回到我的程序。
This is annoying when doing development without a network connection, or if the remote server is down. Is there a way to update the timeout on my ServerProxy object?
在没有网络连接的情况下进行开发或远程服务器关闭时,这很烦人。有没有办法更新我的 ServerProxy 对象的超时时间?
I can't see a clear way to get access to the socket to update it.
我看不到访问套接字以更新它的明确方法。
回答by azarias
An more straightforward solution is at: http://www.devpicayune.com/entry/200609191448
更直接的解决方案是: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
回答by antonylesuisse
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()
回答by Markus Amalthea Magnuson
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.
起初我没有意识到xmlrpclib
有旧式的类,所以我发现它很有用,对此发表评论,否则一切都应该是不言自明的。
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.
我不明白为什么httplib.HTTP
还必须被子类化,如果有人可以启发我,请这样做。上述解决方案已尝试并有效。
回答by mtasic85
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'.
这是适用于 Python 2.7(可能适用于其他 2.x 版本的 Python)的代码,不会引发AttributeError,实例没有属性 '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)
回答by KangOl
Based on the one from antonylesuisse, a working version (on python >= 2.6).
基于 antonylesuisse 的一个,一个工作版本(在 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)
回答by monkut
Here is a verbatim copy from http://code.activestate.com/recipes/473878/
这是来自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
回答by gecco
Here another smart and very pythonicsolution using Python's with
statement:
这是另一个使用 Python语句的智能且非常Pythonic 的解决方案with
:
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()
回答by Slava
The following example works with Python 2.7.4.
以下示例适用于 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)
回答by lengxuehx
Based on the one from antonylesuisse, but works on Python 2.7.5, resolving the problem:AttributeError: TimeoutHTTP instance has no attribute 'getresponse'
基于 antonylesuisse 的,但适用于 Python 2.7.5,解决了问题: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()