Skip to content

Commit

Permalink
lfs: add support for rate limit retries (#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
sisp authored Mar 15, 2024
1 parent a96c366 commit 5d237d7
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/scmrepo/git/lfs/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
from abc import abstractmethod
from collections.abc import Iterable, Iterator
from contextlib import AbstractContextManager, contextmanager, suppress
from http import HTTPStatus
from tempfile import NamedTemporaryFile
from time import time
from typing import TYPE_CHECKING, Any, Optional

import aiohttp
Expand Down Expand Up @@ -64,11 +66,12 @@ async def get_client(**kwargs):
sock_connect=self._REQUEST_TIMEOUT,
sock_read=self._REQUEST_TIMEOUT,
),
retry_options=ExponentialRetry(
retry_options=_ExponentialRetry(
attempts=self._SESSION_RETRIES,
factor=self._SESSION_BACKOFF_FACTOR,
max_timeout=self._REQUEST_TIMEOUT,
exceptions={aiohttp.ClientError},
statuses={HTTPStatus.TOO_MANY_REQUESTS},
),
**kwargs,
)
Expand Down Expand Up @@ -272,3 +275,18 @@ def _as_atomic(to_info: str, create_parents: bool = False) -> Iterator[str]:
raise
else:
shutil.move(tmp_file.name, to_info)


class _ExponentialRetry(ExponentialRetry):
def get_timeout(
self, attempt: int, response: Optional[aiohttp.ClientResponse] = None
) -> float:
if response is not None and response.status == HTTPStatus.TOO_MANY_REQUESTS:
if "Retry-After" in response.headers:
with suppress(ValueError):
return float(response.headers["Retry-After"])
for k in ["RateLimit-Reset", "X-RateLimit-Reset"]:
if k in response.headers:
with suppress(ValueError):
return float(response.headers[k]) - time()
return super().get_timeout(attempt, response)

0 comments on commit 5d237d7

Please sign in to comment.