From c6b14f94c5021452796d7bd151c2c98ae983afdd Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Wed, 22 Jul 2015 14:53:32 -0500 Subject: [PATCH] Set reasonable defaults for TCP Keep-Alive Previously we simply turned on TCP Keep-Alive which relied on per-distribution, per-operating system defaults for keep-alive options. Here we set reasonable defaults since long running processes can get stuck for hours on end by using system defaults. This also adds comments around the options to explain why they're being set. Closes-bug: 1477275 Related-bug: 1323862 Change-Id: Ibd53ae2d4d2455db0ebc9951e5c764befc57850f --- keystoneclient/session.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/keystoneclient/session.py b/keystoneclient/session.py index 14edf46c..d353c988 100644 --- a/keystoneclient/session.py +++ b/keystoneclient/session.py @@ -899,11 +899,36 @@ class Session(object): class TCPKeepAliveAdapter(requests.adapters.HTTPAdapter): - """The custom adapter used to set TCP Keep-Alive on all connections.""" + """The custom adapter used to set TCP Keep-Alive on all connections. + + This Adapter also preserves the default behaviour of Requests which + disables Nagle's Algorithm. See also: + http://blogs.msdn.com/b/windowsazurestorage/archive/2010/06/25/nagle-s-algorithm-is-not-friendly-towards-small-requests.aspx + """ def init_poolmanager(self, *args, **kwargs): if requests.__version__ >= '2.4.1': - kwargs.setdefault('socket_options', [ + socket_options = [ + # Keep Nagle's algorithm off (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1), + # Turn on TCP Keep-Alive (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), - ]) + # Set the maximum number of keep-alive probes + (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 4), + # Send keep-alive probes every 15 seconds + (socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 15), + ] + + # Some operating systems (e.g., OSX) do not support setting + # keepidle + if hasattr(socket, 'TCP_KEEPIDLE'): + socket_options += [ + # Wait 60 seconds before sending keep-alive probes + (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) + ] + + # After waiting 60 seconds, and then sending a probe once every 15 + # seconds 4 times, these options should ensure that a connection + # hands for no longer than 2 minutes before a ConnectionError is + # raised. + kwargs.setdefault('socket_options', socket_options) super(TCPKeepAliveAdapter, self).init_poolmanager(*args, **kwargs)