Skip to content

Commit

Permalink
Enable TCP keep alive on HTTP socket level
Browse files Browse the repository at this point in the history
This commit changes the socket options of a connection in a way that
keepalive (socket.SO_KEEPALIVE) is enabled by default. If enabled, the
kernel settings can be overwritten by individual options. Setting the
socket options is still handled by urllib3.

Reference: https://urllib3.readthedocs.io/en/latest/reference/urllib3.connection.html#urllib3.connection.HTTPConnection

The new arguments for `crate.client.connect` and respectively
`crate.client.connection.Connection` are:

* `socket_keepalive`: (optional, defaults to ``True``)
  Enable TCP keepalive on socket level.
* `socket_tcp_keepidle`: (optional)
  Set the `TCP_KEEPIDLE` socket option, which overrides
  `net.ipv4.tcp_keepalive_time` kernel setting if `socket_keepalive`
  is `True`.
* `socket_tcp_keepintvl`: (optional)
  Set the `TCP_KEEPINTVL` socket option, which overrides
  `net.ipv4.tcp_keepalive_intvl` kernel setting if `socket_keepalive`
  is `True`.
* `socket_tcp_keepcnt`: (optional)
  Set the `TCP_KEEPCNT` socket option, which overrides
  `net.ipv4.tcp_keepalive_probes` kernel setting if `socket_keepalive`
  is `True`.
  • Loading branch information
chaudum committed Sep 11, 2020
1 parent 89f3c22 commit afb3b0b
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 97 deletions.
7 changes: 7 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ Changes for crate
Unreleased
==========

- Enabled TCP keepalive on socket level and support for setting socket options
when creating the connection. The supported options are:

- ``TCP_KEEPIDLE`` (overriding ``net.ipv4.tcp_keepalive_time``)
- ``TCP_KEEPINTVL`` (overriding ``net.ipv4.tcp_keepalive_intvl``)
- ``TCP_KEEPCNT`` (overriding ``net.ipv4.tcp_keepalive_probes``)

- Propagate connect parameter ``pool_size`` to urllib3 as ``maxsize`` parameter
in order to make the connection pool size configurable.

Expand Down
40 changes: 36 additions & 4 deletions docs/connect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,51 @@ the optional ``error_trace`` argument to ``True``, like so::

>>> connection = client.connect(..., error_trace=True)

.. _authentication:

Backoff Factor
..............
--------------

When attempting to make a request, the connection can be configured so that
retries are made in increasing time intervals. This can be configured like so::

>>> connection = client.connect(..., backoff_factor=0.1)

If ``backoff_factor``is set to 0.1, then the delay between retries will be 0.0,
If ``backoff_factor`` is set to 0.1, then the delay between retries will be 0.0,
0.1, 0.2, 0.4 etc. The maximum backoff factor cannot exceed 120 seconds and by
default its value is 0.

Socket Options
--------------

Creating connections uses `urllib3 default socket options`_ but additionally
enables TCP keepalive by setting ``socket.SO_KEEPALIVE`` to ``1``.

Keepalive can be disabled using the ``socket_keepalive`` argument, like so::

>>> connection = client.connect(..., socket_keepalive=False)

If keepalive is enabled (default), there are three additional, optional socket
options that can be configured via connection arguments.

:``socket_tcp_keepidle``:

Set the ``TCP_KEEPIDLE`` socket option, which overrides
``net.ipv4.tcp_keepalive_time`` kernel setting if ``socket_keepalive`` is
``True``.

:``socket_tcp_keepintvl``:

Set the ``TCP_KEEPINTVL`` socket option, which overrides
``net.ipv4.tcp_keepalive_intvl`` kernel setting if ``socket_keepalive`` is
``True``.

:``socket_tcp_keepcnt``:

Set the ``TCP_KEEPCNT`` socket option, which overrides
``net.ipv4.tcp_keepalive_probes`` kernel setting if ``socket_keepalive`` is
``True``.

.. _authentication:

Authentication
==============

Expand Down Expand Up @@ -247,3 +278,4 @@ Once you're connected, you can :ref:`query CrateDB <query>`.
.. _socket timeout: https://docs.python.org/2/library/socket.html#socket.getdefaulttimeout
.. _SQLAlchemy: http://www.sqlalchemy.org/
.. _tracebacks: https://docs.python.org/3/library/traceback.html
.. _urllib3 default socket options: https://urllib3.readthedocs.io/en/latest/reference/urllib3.connection.html#urllib3.connection.HTTPConnection
2 changes: 1 addition & 1 deletion src/crate/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# with Crate these terms will supersede the license and you may use the
# software solely pursuant to the terms of the relevant commercial agreement.

from .connection import connect
from .connection import Connection as connect
from .exceptions import Error

__all__ = [
Expand Down
133 changes: 67 additions & 66 deletions src/crate/client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,65 @@ def __init__(self,
username=None,
password=None,
schema=None,
pool_size=None):
pool_size=None,
socket_keepalive=True,
socket_tcp_keepidle=None,
socket_tcp_keepintvl=None,
socket_tcp_keepcnt=None,
):
"""
:param servers:
either a string in the form of '<hostname>:<port>'
or a list of servers in the form of ['<hostname>:<port>', '...']
:param timeout:
(optional)
define the retry timeout for unreachable servers in seconds
:param backoff_factor:
(optional)
define the retry interval for unreachable servers in seconds
:param client:
(optional - for testing)
client used to communicate with crate.
:param verify_ssl_cert:
if set to ``True`` verify the servers SSL server certificate.
defaults to ``False``
:param ca_cert:
a path to a CA certificate to use when verifying the SSL server
certificate.
:param error_trace:
if set to ``True`` return a whole stacktrace of any server error if
one occurs
:param cert_file:
a path to the client certificate to present to the server.
:param key_file:
a path to the client key to use when communicating with the server.
:param username:
the username in the database.
:param password:
the password of the user in the database.
:param pool_size:
(optional)
Number of connections to save that can be reused.
More than 1 is useful in multithreaded situations.
:param socket_keepalive:
(optional, defaults to ``True``)
Enable TCP keepalive on socket level.
:param socket_tcp_keepidle:
(optional)
Set the ``TCP_KEEPIDLE`` socket option, which overrides
``net.ipv4.tcp_keepalive_time`` kernel setting if ``socket_keepalive``
is ``True``.
:param socket_tcp_keepintvl:
(optional)
Set the ``TCP_KEEPINTVL`` socket option, which overrides
``net.ipv4.tcp_keepalive_intvl`` kernel setting if ``socket_keepalive``
is ``True``.
:param socket_tcp_keepcnt:
(optional)
Set the ``TCP_KEEPCNT`` socket option, which overrides
``net.ipv4.tcp_keepalive_probes`` kernel setting if ``socket_keepalive``
is ``True``.
"""
if client:
self.client = client
else:
Expand All @@ -56,7 +114,12 @@ def __init__(self,
username=username,
password=password,
schema=schema,
pool_size=pool_size)
pool_size=pool_size,
socket_keepalive=socket_keepalive,
socket_tcp_keepidle=socket_tcp_keepidle,
socket_tcp_keepintvl=socket_tcp_keepintvl,
socket_tcp_keepcnt=socket_tcp_keepcnt,
)
self.lowest_server_version = self._lowest_server_version()
self._closed = False

Expand Down Expand Up @@ -113,67 +176,5 @@ def __exit__(self, *excs):
self.close()


def connect(servers=None,
timeout=None,
backoff_factor=0,
client=None,
verify_ssl_cert=False,
ca_cert=None,
error_trace=False,
cert_file=None,
key_file=None,
username=None,
password=None,
schema=None,
pool_size=None):
""" Create a :class:Connection object
:param servers:
either a string in the form of '<hostname>:<port>'
or a list of servers in the form of ['<hostname>:<port>', '...']
:param timeout:
(optional)
define the retry timeout for unreachable servers in seconds
:param backoff_factor:
(optional)
define the retry interval for unreachable servers in seconds
:param client:
(optional - for testing)
client used to communicate with crate.
:param verify_ssl_cert:
if set to ``True`` verify the servers SSL server certificate.
defaults to ``False``
:param ca_cert:
a path to a CA certificate to use when verifying the SSL server
certificate.
:param error_trace:
if set to ``True`` return a whole stacktrace of any server error if
one occurs
:param cert_file:
a path to the client certificate to present to the server.
:param key_file:
a path to the client key to use when communicating with the server.
:param username:
the username in the database.
:param password:
the password of the user in the database.
:param pool_size:
(optional)
Number of connections to save that can be reused.
More than 1 is useful in multithreaded situations.
>>> connect(['host1:4200', 'host2:4200'])
<Connection <Client ['http://host1:4200', 'http://host2:4200']>>
"""
return Connection(servers=servers,
timeout=timeout,
backoff_factor=backoff_factor,
pool_size=pool_size,
client=client,
verify_ssl_cert=verify_ssl_cert,
ca_cert=ca_cert,
error_trace=error_trace,
cert_file=cert_file,
key_file=key_file,
username=username,
password=password,
schema=schema)
# For backwards compatibility and not to break existing imports
connect = Connection
2 changes: 1 addition & 1 deletion src/crate/client/doctests/blob.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ bloba API.

Create a connection::

>>> from crate.client.connection import connect
>>> from crate.client import connect
>>> client = connect([crate_host])

Get a blob container::
Expand Down
Loading

0 comments on commit afb3b0b

Please sign in to comment.