Browse Source

Merge "Add TCP keepalive to gitlab"

changes/59/793159/14
Zuul 2 weeks ago
committed by Gerrit Code Review
parent
commit
dd38659335
  1. 8
      doc/source/reference/drivers/gitlab.rst
  2. 8
      tests/base.py
  3. 11
      zuul/driver/gitlab/gitlabconnection.py
  4. 36
      zuul/lib/http.py

8
doc/source/reference/drivers/gitlab.rst

@ -101,7 +101,7 @@ The supported options in ``zuul.conf`` connections are:
.. attr:: cloneurl
:default: {baseurl}
Omit to clone using http(s) or set to ``ssh://git@{server}``.
If **api_token_name** is set and **cloneurl** is either omitted or is
set without credentials, **cloneurl** will be modified to use credentials
@ -109,6 +109,12 @@ The supported options in ``zuul.conf`` connections are:
If **cloneurl** is defined with credentials, it will be used as is,
without modification from the driver.
.. attr:: keepalive
:default: 60
TCP connection keepalive timeout; ``0`` disables.
Trigger Configuration
---------------------

8
tests/base.py

@ -1927,7 +1927,7 @@ class FakeGitlabConnection(gitlabconnection.GitlabConnection):
connection_config)
self.merge_requests = changes_db
self.gl_client = FakeGitlabAPIClient(
self.baseurl, self.api_token, merge_requests_db=changes_db)
self.baseurl, self.api_token, 60, merge_requests_db=changes_db)
self.rpcclient = rpcclient
self.upstream_root = upstream_root
self.mr_number = 0
@ -2024,8 +2024,10 @@ FakeBranch = namedtuple('Branch', ('name', 'protected'))
class FakeGitlabAPIClient(gitlabconnection.GitlabAPIClient):
log = logging.getLogger("zuul.test.FakeGitlabAPIClient")
def __init__(self, baseurl, api_token, merge_requests_db={}):
super(FakeGitlabAPIClient, self).__init__(baseurl, api_token)
def __init__(self, baseurl, api_token, keepalive,
merge_requests_db={}):
super(FakeGitlabAPIClient, self).__init__(
baseurl, api_token, keepalive)
self.merge_requests = merge_requests_db
self.fake_repos = defaultdict(lambda: IterableList('name'))
self.community_edition = False

11
zuul/driver/gitlab/gitlabconnection.py

@ -30,6 +30,7 @@ from typing import List, Optional
from zuul.connection import CachedBranchConnection, ZKChangeCacheMixin
from zuul.web.handler import BaseWebController
from zuul.lib.http import ZuulHTTPAdapter
from zuul.lib.logutil import get_annotated_logger
from zuul.exceptions import MergeFailure
from zuul.model import Branch, Project, Ref, Tag
@ -254,11 +255,12 @@ class GitlabAPIClientException(Exception):
class GitlabAPIClient():
log = logging.getLogger("zuul.GitlabAPIClient")
def __init__(self, baseurl, api_token):
def __init__(self, baseurl, api_token, keepalive):
self.session = requests.Session()
retry = urllib3.util.Retry(total=8,
backoff_factor=0.1)
adapter = requests.adapters.HTTPAdapter(max_retries=retry)
adapter = ZuulHTTPAdapter(keepalive=keepalive,
max_retries=retry)
self.session.mount(baseurl, adapter)
self.baseurl = '%s/api/v4' % baseurl
self.api_token = api_token
@ -439,7 +441,10 @@ class GitlabConnection(ZKChangeCacheMixin, CachedBranchConnection):
'api_token_name', '')
self.api_token = self.connection_config.get(
'api_token', '')
self.gl_client = GitlabAPIClient(self.baseurl, self.api_token)
self.keepalive = self.connection_config.get('keepalive', 60)
self.gl_client = GitlabAPIClient(self.baseurl, self.api_token,
self.keepalive)
self.sched = None
self.source = driver.getSource(self)

36
zuul/lib/http.py

@ -0,0 +1,36 @@
# Copyright 2021 Acme Gating, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import socket
from requests.adapters import HTTPAdapter
from urllib3.connection import HTTPConnection
class ZuulHTTPAdapter(HTTPAdapter):
"A requests HTTPAdapter class which supports TCP keepalives"
def __init__(self, *args, **kw):
self.keepalive = int(kw.pop('keepalive', 0))
super().__init__(*args, **kw)
def init_poolmanager(self, *args, **kw):
if self.keepalive:
ka = self.keepalive
kw['socket_options'] = HTTPConnection.default_socket_options + [
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, ka),
(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, ka),
(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2),
]
return super().init_poolmanager(*args, **kw)
Loading…
Cancel
Save