Skip to content

Commit bd2e7d6

Browse files
authored
fix(launch-darkly-importer): Rate limit responses with no retry information not expected (#5529)
1 parent e1606bd commit bd2e7d6

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

api/integrations/launch_darkly/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from integrations.launch_darkly import types as ld_types
1111
from integrations.launch_darkly.constants import (
12+
BACKOFF_DEFAULT_RETRY_AFTER_SECONDS,
1213
BACKOFF_MAX_RETRIES,
1314
LAUNCH_DARKLY_API_BASE_URL,
1415
LAUNCH_DARKLY_API_ITEM_COUNT_LIMIT_PER_PAGE,
@@ -41,6 +42,9 @@ def _get_retry_after(exc: RequestException) -> float | None:
4142
return float(retry_after)
4243
if ratelimit_reset := headers.get("X-Ratelimit-Reset"):
4344
return float(ratelimit_reset) - timezone_now().timestamp()
45+
# We have no retry information, use a default backoff time
46+
# of 10 seconds as per LD documentation.
47+
return BACKOFF_DEFAULT_RETRY_AFTER_SECONDS
4448
return None
4549

4650
def _wait_gen() -> Generator[float, None, None]:

api/integrations/launch_darkly/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
LAUNCH_DARKLY_IMPORTED_DEFAULT_TAG_LABEL = "Imported"
99

1010
BACKOFF_MAX_RETRIES = 5
11+
BACKOFF_DEFAULT_RETRY_AFTER_SECONDS = 10

api/tests/unit/integrations/launch_darkly/test_client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,39 @@ def test_launch_darkly_client__rate_limit_invalid_response__raises_expected(
325325
# When & Then
326326
with pytest.raises(HTTPError):
327327
client.get_project(project_key=project_key)
328+
329+
330+
def test_launch_darkly_client__rate_limit_no_headers__waits_expected(
331+
request: pytest.FixtureRequest,
332+
mocker: MockerFixture,
333+
requests_mock: RequestsMockerFixture,
334+
) -> None:
335+
# Given
336+
token = "test-token"
337+
project_key = "test-project-key"
338+
339+
mocker.patch(
340+
"integrations.launch_darkly.client.BACKOFF_DEFAULT_RETRY_AFTER_SECONDS",
341+
new=0.1,
342+
)
343+
344+
example_response_content = (
345+
request.path.parent / "example_api_responses/getProject.json"
346+
).read_text()
347+
expected_result = json.loads(example_response_content)
348+
349+
requests_mock.get(
350+
"https://app.launchdarkly.com/api/v2/projects/test-project-key",
351+
[
352+
{"status_code": 429},
353+
{"status_code": 200, "text": example_response_content},
354+
],
355+
)
356+
357+
client = LaunchDarklyClient(token=token)
358+
359+
# When
360+
result = client.get_project(project_key=project_key)
361+
362+
# Then
363+
assert result == expected_result

0 commit comments

Comments
 (0)