Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit 6f28470

Browse files
fix: handle Minio client retries better (#511)
1 parent 04b5f81 commit 6f28470

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

shared/storage/minio.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from io import BytesIO
88
from typing import BinaryIO, overload
99

10+
import certifi
11+
import urllib3
1012
from minio import Minio
1113
from minio.credentials import (
1214
ChainedProvider,
@@ -15,12 +17,17 @@
1517
IamAwsProvider,
1618
)
1719
from minio.error import MinioException, S3Error
20+
from urllib3 import Retry
21+
from urllib3.util import Timeout
1822

1923
from shared.storage.base import CHUNK_SIZE, BaseStorageService
2024
from shared.storage.exceptions import BucketAlreadyExistsError, FileNotInStorageError
2125

2226
log = logging.getLogger(__name__)
2327

28+
CONNECT_TIMEOUT = 10
29+
READ_TIMEOUT = 60
30+
2431

2532
# Service class for interfacing with codecov's underlying storage layer, minio
2633
class MinioStorageService(BaseStorageService):
@@ -80,6 +87,24 @@ def init_minio_client(
8087
if port is not None:
8188
host = "{}:{}".format(host, port)
8289

90+
http_client = urllib3.PoolManager(
91+
timeout=Timeout(connect=CONNECT_TIMEOUT, read=READ_TIMEOUT),
92+
maxsize=10,
93+
cert_reqs="CERT_REQUIRED",
94+
ca_certs=os.environ.get("SSL_CERT_FILE") or certifi.where(),
95+
retries=Retry(
96+
total=5,
97+
backoff_factor=1,
98+
status_forcelist=[
99+
408,
100+
429,
101+
500,
102+
502,
103+
503,
104+
504,
105+
], # https://cloud.google.com/storage/docs/retry-strategy#python
106+
),
107+
)
83108
if iam_auth:
84109
return Minio(
85110
host,
@@ -92,13 +117,15 @@ def init_minio_client(
92117
EnvAWSProvider(),
93118
]
94119
),
120+
http_client=http_client,
95121
)
96122
return Minio(
97123
host,
98124
access_key=access_key,
99125
secret_key=secret_key,
100126
secure=verify_ssl,
101127
region=region,
128+
http_client=http_client,
102129
)
103130

104131
# writes the initial storage bucket to storage via minio.

tests/unit/storage/test_minio.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,11 @@ def test_minio_without_ports(self, mocker):
134134
storage = MinioStorageService(minio_no_ports_config)
135135
assert storage.minio_config == minio_no_ports_config
136136
mocked_minio_client.assert_called_with(
137-
"cute_url_no_ports", credentials=mocker.ANY, secure=False, region=None
137+
"cute_url_no_ports",
138+
credentials=mocker.ANY,
139+
http_client=mocker.ANY,
140+
secure=False,
141+
region=None,
138142
)
139143

140144
def test_minio_with_ports(self, mocker):
@@ -151,7 +155,11 @@ def test_minio_with_ports(self, mocker):
151155
storage = MinioStorageService(minio_no_ports_config)
152156
assert storage.minio_config == minio_no_ports_config
153157
mocked_minio_client.assert_called_with(
154-
"cute_url_no_ports:9000", credentials=mocker.ANY, secure=False, region=None
158+
"cute_url_no_ports:9000",
159+
credentials=mocker.ANY,
160+
http_client=mocker.ANY,
161+
secure=False,
162+
region=None,
155163
)
156164

157165
def test_minio_with_region(self, mocker):
@@ -171,6 +179,7 @@ def test_minio_with_region(self, mocker):
171179
mocked_minio_client.assert_called_with(
172180
"cute_url_no_ports:9000",
173181
credentials=mocker.ANY,
182+
http_client=mocker.ANY,
174183
secure=False,
175184
region="example",
176185
)

0 commit comments

Comments
 (0)