Use TCP Keep-Alive on the socket level

There is not a way to pass the socket options to the HTTPAdapter upon
creation so we have to sub-class it and override the init_poolmanager
method.  This also requires at least python-requests 2.4.0 but that
has 2 severe bugs that were fixed in 2.4.1. If we try to fix this
without a hard lower limit, we will not be able to properly set these
options on the socket at creation time.

Change-Id: I06e0d2c67d3197607e5f23f623c8fca69e1b23d7
Closes-bug: 1323862
This commit is contained in:
Ian Cordasco 2014-09-10 15:13:20 -05:00
parent 4dbf1323cc
commit 7713fa0b18
2 changed files with 14 additions and 2 deletions

View File

@ -28,6 +28,7 @@ import hashlib
import logging
import os
import re
import socket
import time
from keystoneclient import adapter
@ -48,6 +49,17 @@ from novaclient import service_catalog
from novaclient import utils
class TCPKeepAliveAdapter(adapters.HTTPAdapter):
"""The custom adapter used to set TCP Keep-Alive on all connections."""
def init_poolmanager(self, *args, **kwargs):
if requests.__version__ >= '2.4.1':
kwargs.setdefault('socket_options', [
(socket.IPROTO_TCP, socket.TCP_NODELAY, 1),
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
])
super(TCPKeepAliveAdapter, self).init_poolmanager(*args, **kwargs)
class _ClientConnectionPool(object):
def __init__(self):
@ -58,7 +70,7 @@ class _ClientConnectionPool(object):
Store and reuse HTTP adapters per Service URL.
"""
if url not in self._adapters:
self._adapters[url] = adapters.HTTPAdapter()
self._adapters[url] = TCPKeepAliveAdapter()
return self._adapters[url]

View File

@ -31,7 +31,7 @@ import novaclient.v3.client
class ClientConnectionPoolTest(utils.TestCase):
@mock.patch("novaclient.client.adapters.HTTPAdapter")
@mock.patch("novaclient.client.TCPKeepAliveAdapter")
def test_get(self, mock_http_adapter):
mock_http_adapter.side_effect = lambda: mock.Mock()
pool = novaclient.client._ClientConnectionPool()