Skip to content

Commit d493e9c

Browse files
authored
[CRCR] Raise default callback rate limit to 60/min/repo (#8203)
## Summary The cross-repo CI relay **callback** Lambda (`crcr-callback-prod` / `cross_repo_ci_callback`) enforces a **per-repo** sliding-window rate limit in `utils/redis_helper.check_rate_limit`, defaulting to **20 requests/min** when `RATE_LIMIT_PER_MIN` is unset: ```python # utils/config.py rate_limit_per_min = int(os.getenv("RATE_LIMIT_PER_MIN", "20")) ``` No env override is deployed (the deploy Makefile only runs `update-function-code`, and no IaC sets the variable), so the Lambda runs at the in-code default of 20/min. That 429s legitimate job-fan-out bursts — e.g. a downstream reporting `in_progress` for many jobs near workflow start — which is what trips the L2 edge-case tests for `TorchedHat/pytorch-redhat-ci`: ``` ##[error]Callback server returned HTTP 429. {"detail": "rate limit exceeded for TorchedHat/pytorch-redhat-ci"} ``` ## Change - `utils/config.py`: raise the default `RATE_LIMIT_PER_MIN` from `20` → `60` (1 callback/sec/repo). An env var still overrides it for per-deployment tuning. - `utils/hud.py`: guard the user-facing "retry after N seconds" message with `max(1, 60 // rate_limit_per_min)` so it stays sensible if the limit is ever set above 60 (otherwise `60 // 61 == 0`). ## Why 60 is safe - The limit is **per-repo** (key `oot:rate:{repo}`), so aggregate downstream load = `60 × (#L2+ repos)`. There are currently 2 L2 repos (`pytorch/crcr-test`, `TorchedHat/pytorch-redhat-ci`), so worst case ≈ 2 callbacks/sec — trivial for the HUD API / DynamoDB, even accounting for the up-to-4× amplification from `HUD_MAX_RETRIES` during a HUD slowdown. - Still a real abuse guard at 1 callback/sec/repo. - The Redis ops per callback are negligible; the only meaningful downstream cost is the single HUD POST, which this comfortably bounds. ## Deploy note Only the **callback** Lambda evaluates the limit (`webhook` never calls `check_rate_limit`), so only `cross_repo_ci_callback` needs redeploying: ``` make -C aws/lambda/cross_repo_ci_relay deploy-callback CALLBACK_FUNCTION_NAME=cross_repo_ci_callback ``` ## Test plan - Existing unit tests unaffected: `test_callback_handler.py` / `test_redis_helper.py` set `cfg.rate_limit_per_min` explicitly per-test (independent of the default); `test_config.py` does not assert the default value. - AI assistance (Claude) was used to prepare this change. --------- Signed-off-by: Andrey Talman <atalman@fb.com>
1 parent 50358ee commit d493e9c

3 files changed

Lines changed: 9 additions & 3 deletions

File tree

aws/lambda/cross_repo_ci_relay/tests/test_hud.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@
77
from utils.misc import HTTPException
88

99

10-
def _cfg(url="http://hud/api/oot-ci-events", key="bot-key", max_retries=3):
10+
def _cfg(
11+
url="http://hud/api/oot-ci-events",
12+
key="bot-key",
13+
max_retries=3,
14+
rate_limit_per_min=60,
15+
):
1116
cfg = MagicMock()
1217
cfg.hud_api_url = url
1318
cfg.hud_bot_key = key
1419
cfg.hud_max_retries = max_retries
20+
cfg.rate_limit_per_min = rate_limit_per_min
1521
return cfg
1622

1723

aws/lambda/cross_repo_ci_relay/utils/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def from_env(cls) -> "RelayConfig":
140140
raise RuntimeError("HUD_MAX_RETRIES must be a non-negative integer")
141141

142142
try:
143-
rate_limit_per_min = int(os.getenv("RATE_LIMIT_PER_MIN", "20"))
143+
rate_limit_per_min = int(os.getenv("RATE_LIMIT_PER_MIN", "60"))
144144
if rate_limit_per_min <= 0:
145145
raise ValueError("must be positive")
146146
except ValueError:

aws/lambda/cross_repo_ci_relay/utils/hud.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def forward_to_hud(config: RelayConfig, trusted: dict, untrusted: dict) -> None:
9797
"An internal failure occurred. "
9898
"Your update was not saved, but the CI run is still valid. "
9999
"You can attempt progressive retries after "
100-
f"{60 // config.rate_limit_per_min} seconds or ignore this failure.",
100+
f"{max(1, 60 // config.rate_limit_per_min)} seconds or ignore this failure.",
101101
) from last_exception
102102
else:
103103
logger.error(

0 commit comments

Comments
 (0)