Skip to content

Commit 2038d7d

Browse files
committed
Added retry middleware to aiohttp musl requests
I have been notified by @guyush1 that the website is unstable, so we retry the download 5 times.
1 parent 8adc0f8 commit 2038d7d

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@ RUN apt update && apt install -y \
2525
patch \
2626
pkg-config \
2727
python3.12 \
28-
python3-aiohttp \
28+
python3-pip \
2929
libpython3-dev \
3030
texinfo \
3131
wget \
3232
xz-utils
3333

34+
# We require aiohttp >= 3.12 (For client middleware support), which is newer than the currently
35+
# available python3-aiohttp's version in Ubuntu.
36+
RUN python3.12 -m pip install --break-system-packages aiohttp
37+
3438
COPY src/docker_utils/download_musl_toolchains.py .
3539
RUN python3.12 -u download_musl_toolchains.py
3640

src/docker_utils/download_musl_toolchains.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python3.12
22

3-
from typing import List
43
from pathlib import Path
4+
from typing import List
55

66
import tarfile
77
import tempfile
@@ -10,6 +10,7 @@
1010
import asyncio
1111

1212
import aiohttp
13+
import aiohttp.client_exceptions
1314

1415
ARCHS = {
1516
"x86_64" : "https://more.musl.cc/11/x86_64-linux-musl/x86_64-linux-musl-cross.tgz",
@@ -23,9 +24,33 @@
2324
MUSL_TOOLCHAINS_DIR = Path("/musl-toolchains")
2425
ENTRYPOINT = Path("/entrypoint.sh")
2526

27+
NUM_RETRIES = 10
28+
RETRY_WAIT = 3
29+
30+
async def retry_middleware(req: aiohttp.ClientRequest, handler: aiohttp.ClientHandlerType, max_retries = NUM_RETRIES) -> aiohttp.ClientResponse:
31+
# If every retry ends in a timeoout, resp will not be defined. In such a case we want to raie
32+
# last timeout that has happened as we don't have a valid or invalid response to return.
33+
last_exception = None
34+
35+
for _ in range(max_retries):
36+
try:
37+
resp = await handler(req)
38+
if resp.ok:
39+
return resp
40+
except aiohttp.client_exceptions.ConnectionTimeoutError as e:
41+
last_exception = e
42+
43+
await asyncio.sleep(RETRY_WAIT)
44+
45+
if resp is None:
46+
raise last_exception
47+
48+
return resp
49+
2650
async def download_file(url: str, filename: str):
27-
async with aiohttp.ClientSession() as session:
51+
async with aiohttp.ClientSession(middlewares=(retry_middleware,)) as session:
2852
async with session.get(url) as response:
53+
response.raise_for_status()
2954
with open(filename, 'wb') as f:
3055
async for data in response.content.iter_chunked(CHUNK_SIZE):
3156
f.write(data)

0 commit comments

Comments
 (0)