Merge "Add TCP keepalive to gitlab"

This commit is contained in:
Zuul 2021-10-06 10:00:12 +00:00 committed by Gerrit Code Review
commit dd38659335
4 changed files with 56 additions and 7 deletions

View File

@ -109,6 +109,12 @@ The supported options in ``zuul.conf`` connections are:
If **cloneurl** is defined with credentials, it will be used as is, If **cloneurl** is defined with credentials, it will be used as is,
without modification from the driver. without modification from the driver.
.. attr:: keepalive
:default: 60
TCP connection keepalive timeout; ``0`` disables.
Trigger Configuration Trigger Configuration
--------------------- ---------------------

View File

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

View File

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

36
zuul/lib/http.py Normal file
View File

@ -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)