Add support for TCP keep alive in gerritlib

Clients using gerritlib behind NAT/firewall
can be stuck when the NAT/firewall discard
packets belong to the TCP connection after extended
silent periods thinking the connection is dead.

This change allows clients using gerritlib to set
keep alive interval to a non zero value. This will
enable TCP keep alive packets to be sent in
configured intervals keeping the TCP connections alive.

Change-Id: I588706bb51ce41810cd2243f4969763d193d1d55
This commit is contained in:
Arun S A G 2020-09-09 17:22:29 -07:00
parent 6058d994b8
commit 40858f3678
3 changed files with 14 additions and 7 deletions

View File

@ -5,7 +5,7 @@ Usage
Example usage::
import gerritlib.gerrit as gerrit
g = gerrit.Gerrit('gerrit_host', 'username', keyfile='/home/username/.ssh/id_rsa.pub')
g = gerrit.Gerrit('gerrit_host', 'username', keyfile='/home/username/.ssh/id_rsa.pub', keep_alive_interval=60)
# manage projects
g.createProject('test', description='a test project')
@ -18,4 +18,4 @@ Example usage::
print(groups)
Look at the :doc:`api` for more details.
Look at the :doc:`api` for more details.

View File

@ -40,7 +40,8 @@ class GerritConnection(object):
log = logging.getLogger("gerrit.GerritConnection")
def __init__(self, username=None, hostname=None, port=29418,
keyfile=None, connection_attempts=-1, retry_delay=5):
keyfile=None, keep_alive=0, connection_attempts=-1,
retry_delay=5):
assert retry_delay >= 0, "Retry delay must be >= 0"
self.username = username
@ -49,6 +50,7 @@ class GerritConnection(object):
self.keyfile = keyfile
self.connection_attempts = int(connection_attempts)
self.retry_delay = float(retry_delay)
self.keep_alive = keep_alive
def connect(self):
"""Attempts to connect and returns the connected client."""
@ -85,6 +87,8 @@ class GerritConnection(object):
username=self.username,
port=self.port,
key_filename=self.keyfile)
if self.keep_alive:
client.get_transport().set_keepalive(self.keep_alive)
return client
except (IOError, paramiko.SSHException) as e:
self.log.exception("Exception connecting to %s:%s",
@ -108,7 +112,7 @@ class GerritWatcher(threading.Thread):
def __init__(
self, gerrit, username=None, hostname=None, port=None,
keyfile=None, connection_attempts=-1, retry_delay=5):
keyfile=None, keep_alive=0, connection_attempts=-1, retry_delay=5):
"""Create a GerritWatcher.
:param gerrit: A GerritConnection instance to pass events to.
@ -122,6 +126,7 @@ class GerritWatcher(threading.Thread):
hostname or gerrit.connection.hostname,
port or gerrit.connection.port,
keyfile or gerrit.connection.keyfile,
keep_alive or gerrit.connection.keep_alive,
connection_attempts,
retry_delay
)
@ -194,8 +199,10 @@ class GerritWatcher(threading.Thread):
class Gerrit(object):
log = logging.getLogger("gerrit.Gerrit")
def __init__(self, hostname, username, port=29418, keyfile=None):
self.connection = GerritConnection(username, hostname, port, keyfile)
def __init__(self, hostname, username, port=29418, keyfile=None,
keep_alive_interval=0):
self.connection = GerritConnection(username, hostname, port, keyfile,
keep_alive=keep_alive_interval)
self.client = None
self.watcher_thread = None
self.event_queue = None

View File

@ -1,4 +1,4 @@
hacking>=0.5.6,<0.11
hacking
sphinx>=1.1.2,<1.2
python-subunit
stestr<3.0.0;python_version<'3.5'