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.
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
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
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)
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)
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()
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()