Skip to content

Commit ae21943

Browse files
subinz1atalman
andauthored
[CRCR] Rename OOT → CRCR in relay Lambda (Redis keys, config, tests) (#8217)
## Summary Part 1 of the OOT → CRCR rename series. Renames all `oot` references to `crcr` in the `cross_repo_ci_relay` Lambda code to align with the official "Cross-Repository CI Relay" (CRCR) terminology. **Changes (6 files):** - **`utils/config.py`** — `oot_status_ttl` → `crcr_status_ttl`, `OOT_STATUS_TTL` → `CRCR_STATUS_TTL` env var, `/oot/results` → `/crcr/results` HUD API path - **`utils/redis_helper.py`** — Redis key prefixes: `oot:state:` → `crcr:state:`, `oot:rate:` → `crcr:rate:`, `oot:allowlist_yaml` → `crcr:allowlist_yaml`, `config.oot_status_ttl` → `config.crcr_status_ttl` - **`README.md`** — Updated key format example and Docker container name - **`tests/test_redis_helper.py`** — Updated mock config field - **`tests/test_callback_handler.py`** — Updated mock config field and URL - **`tests/test_hud.py`** — Updated mock URL **Deployment note:** Existing Redis keys with the `oot:*` prefix will expire naturally via TTL — no migration needed. The `CRCR_STATUS_TTL` env var replaces `OOT_STATUS_TTL` on the Lambda. **Depends on:** HUD-side `/api/crcr/results` endpoint (PR 3 in this series) must be deployed before or alongside this change so the Lambda can forward to the new path. ## Rename series | PR | Scope | Status | |----|-------|--------| | **PR 1 (this)** | Lambda — Redis keys, config, tests | This PR | | PR 2 | ClickHouse — schema + replicator | Upcoming | | PR 3 | Frontend — lib, API, components, queries, tests | Upcoming | ## Test plan - [ ] Verify all existing Lambda unit tests pass with renamed fields - [ ] Confirm `CRCR_STATUS_TTL` env var is read correctly - [ ] Confirm HUD API URL is constructed as `/crcr/results` --------- Co-authored-by: Andrey Talman <atalman@fb.com>
1 parent 32a64d0 commit ae21943

7 files changed

Lines changed: 29 additions & 24 deletions

File tree

aws/lambda/cross_repo_ci_relay/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ The callback endpoint validates incoming callbacks and forwards them to HUD for
4747
- **State machine**: Relay maintains a **unified state machine** in Redis to validate callback lifecycles, compute timing metrics, and support per-workflow tracking:
4848
- **Unified structure**: Single enum `CallbackState` with states `DISPATCHED` (webhook side, keyed by sentinel `run_id=0, run_attempt=0`), `IN_PROGRESS`, and `COMPLETED` (callback side, per-workflow). State records stored as JSON: `{"state": "...", "timestamp": 1234.56}`.
4949
- **Dispatch validation**: `DISPATCHED` state proves valid webhook origin. Callbacks without this state are rejected (no prior dispatch).
50-
- **Workflow-level tracking**: Each workflow has independent state and timestamps keyed by `{run_id}:{run_attempt}` (`oot:state:{delivery_id}:{repo}:{run_id}:{run_attempt}`). Supports multiple workflows per webhook.
50+
- **Workflow-level tracking**: Each workflow has independent state and timestamps keyed by `{run_id}:{run_attempt}` (`crcr:state:{delivery_id}:{repo}:{run_id}:{run_attempt}`). Supports multiple workflows per webhook.
5151
- **Timing metrics**: `queue_time = dispatch_timestamp → in_progress_timestamp`, `execution_time = in_progress_timestamp → completed_timestamp`. Timestamps extracted from state records.
5252
- **State transitions**: Rejects invalid flows (`COMPLETED` without prior `IN_PROGRESS`, duplicate `IN_PROGRESS` for the same `{run_id}:{run_attempt}`, duplicate `COMPLETED`, callbacks without a prior `DISPATCHED` record).
5353
Note that the direction graph below is for a single check run, reruns have different `run_attempt` and are treated as separate workflows, so they won't violate the state machine since they won't have a prior `IN_PROGRESS` or `COMPLETED` record.
@@ -253,7 +253,7 @@ make clean
253253
- A running Redis instance:
254254
```bash
255255
# Using the built-in "default" user with a password:
256-
docker run -d --name oot-redis \
256+
docker run -d --name crcr-redis \
257257
-p 6379:6379 \
258258
redis:7-alpine \
259259
redis-server --requirepass <your-password>

aws/lambda/cross_repo_ci_relay/tests/test_callback_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
def _cfg():
1212
cfg = MagicMock()
13-
cfg.hud_api_url = "http://hud/api/oot-ci-events"
13+
cfg.hud_api_url = "http://hud/api/crcr-ci-events"
1414
cfg.hud_bot_key = "bot-key-123"
1515
cfg.redis_endpoint = "host:6379"
1616
cfg.redis_login = ""
17-
cfg.oot_status_ttl = 259200
17+
cfg.crcr_status_ttl = 259200
1818
cfg.rate_limit_per_min = 20
1919
return cfg
2020

aws/lambda/cross_repo_ci_relay/tests/test_cleanup_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
def _cfg():
1313
cfg = MagicMock()
14-
cfg.hud_api_url = "http://hud/api/oot/results"
14+
cfg.hud_api_url = "http://hud/api/crcr/results"
1515
cfg.hud_bot_key = "bot-key-123"
1616
cfg.zombie_timeout_seconds = 86400
1717
cfg.max_cleanup_workers = 4

aws/lambda/cross_repo_ci_relay/tests/test_hud.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
def _cfg(
11-
url="http://hud/api/oot-ci-events",
11+
url="http://hud/api/crcr-ci-events",
1212
key="bot-key",
1313
max_retries=3,
1414
rate_limit_per_min=60,

aws/lambda/cross_repo_ci_relay/tests/test_redis_helper.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def _cfg():
2222
cfg.redis_endpoint = "host:6379"
2323
cfg.redis_login = ""
2424
cfg.allowlist_ttl_seconds = 600
25-
cfg.oot_status_ttl = 3600
25+
cfg.crcr_status_ttl = 3600
2626
cfg.rate_limit_per_min = 20
2727
return cfg
2828

@@ -311,9 +311,9 @@ def test_add_in_progress_tracker_zadd_with_correct_score(self):
311311
expected_member = "del-123:org/repo:99999:1"
312312
expected_score = now + 86400
313313
client.zadd.assert_called_once_with(
314-
"oot:in_progress", {expected_member: expected_score}
314+
"crcr:in_progress", {expected_member: expected_score}
315315
)
316-
client.expire.assert_called_once_with("oot:in_progress", 172800)
316+
client.expire.assert_called_once_with("crcr:in_progress", 172800)
317317

318318
def test_add_in_progress_tracker_redis_error_is_silent(self):
319319
"""Redis errors are logged but not raised — tracker is best-effort."""
@@ -335,7 +335,7 @@ def test_remove_in_progress_tracker_zrem(self):
335335
remove_in_progress_tracker(cfg, "del-123", "org/repo", 99999, 1, client=client)
336336

337337
client.zrem.assert_called_once_with(
338-
"oot:in_progress", "del-123:org/repo:99999:1"
338+
"crcr:in_progress", "del-123:org/repo:99999:1"
339339
)
340340

341341
def test_remove_in_progress_tracker_redis_error_is_silent(self):
@@ -385,7 +385,7 @@ def get_side_effect(key):
385385
self.assertEqual(results[0]["state_record"].state, CallbackState.IN_PROGRESS)
386386

387387
# Second entry (COMPLETED) had its tracker cleaned up
388-
client.zrem.assert_any_call("oot:in_progress", "del-2:org/repo:20:1")
388+
client.zrem.assert_any_call("crcr:in_progress", "del-2:org/repo:20:1")
389389

390390
def test_scan_expired_skips_missing_state_records(self):
391391
"""Members whose state record is gone are cleaned from the ZSET."""
@@ -403,7 +403,7 @@ def test_scan_expired_skips_missing_state_records(self):
403403

404404
self.assertEqual(results, [])
405405
client.zrem.assert_called_once_with(
406-
"oot:in_progress", "del-missing:org/repo:5:1"
406+
"crcr:in_progress", "del-missing:org/repo:5:1"
407407
)
408408

409409
def test_scan_expired_handles_malformed_member(self):
@@ -420,7 +420,7 @@ def test_scan_expired_handles_malformed_member(self):
420420
results = scan_expired_in_progress(cfg, client=client)
421421

422422
self.assertEqual(results, [])
423-
client.zrem.assert_called_once_with("oot:in_progress", "bad-member")
423+
client.zrem.assert_called_once_with("crcr:in_progress", "bad-member")
424424

425425
def test_set_callback_state_with_payload(self):
426426
"""Payload is stored alongside state and timestamp under a "payload" key."""

aws/lambda/cross_repo_ci_relay/utils/config.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class RelayConfig:
7171
max_dispatch_workers: int
7272
hud_api_url: str
7373
hud_bot_key: str
74-
oot_status_ttl: int
74+
crcr_status_ttl: int
7575
hud_max_retries: int
7676
rate_limit_per_min: int
7777
zombie_timeout_seconds: int
@@ -134,9 +134,12 @@ def from_env(cls) -> "RelayConfig":
134134
)
135135

136136
# GitHub can keep a workflow in `pending` state for up to 3 days before
137-
# auto-cancelling it, so OOT-status records must live at least that long.
137+
# auto-cancelling it, so CRCR-status records must live at least that long.
138138
# Default to 3 days (259200 s).
139-
oot_status_ttl = _check_if_positive_int("OOT_STATUS_TTL", "259200")
139+
try:
140+
crcr_status_ttl = _check_if_positive_int("CRCR_STATUS_TTL", "259200")
141+
except ValueError:
142+
raise RuntimeError("CRCR_STATUS_TTL must be a valid integer")
140143

141144
# Maximum number of retry attempts for HUD API calls.
142145
# Default to 3 retries with exponential backoff.
@@ -169,9 +172,9 @@ def from_env(cls) -> "RelayConfig":
169172
raise RuntimeError(
170173
"HUD_API_URL must use https:// to protect the bot key in transit"
171174
)
172-
# Add hud_api_url ends with /oot/results for flexibility of adding features later
175+
# Add hud_api_url ends with /crcr/results for flexibility of adding features later
173176
if hud_api_url:
174-
hud_api_url = hud_api_url.rstrip("/") + "/oot/results"
177+
hud_api_url = hud_api_url.rstrip("/") + "/crcr/results"
175178

176179
return cls(
177180
github_app_id=_require("GITHUB_APP_ID"),
@@ -185,7 +188,7 @@ def from_env(cls) -> "RelayConfig":
185188
max_dispatch_workers=max_dispatch_workers,
186189
hud_api_url=hud_api_url,
187190
hud_bot_key=hud_bot_key,
188-
oot_status_ttl=oot_status_ttl,
191+
crcr_status_ttl=crcr_status_ttl,
189192
hud_max_retries=hud_max_retries,
190193
rate_limit_per_min=rate_limit_per_min,
191194
zombie_timeout_seconds=zombie_timeout_seconds,

aws/lambda/cross_repo_ci_relay/utils/redis_helper.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414

1515
logger = logging.getLogger(__name__)
1616

17-
_ALLOWLIST_CACHE_KEY = "oot:allowlist_yaml"
18-
_STATE_PREFIX = "oot:state:"
19-
_RATE_LIMIT_PREFIX = "oot:rate:"
20-
_IN_PROGRESS_ZSET = "oot:in_progress"
17+
18+
_ALLOWLIST_CACHE_KEY = "crcr:allowlist_yaml"
19+
_STATE_PREFIX = "crcr:state:"
20+
_RATE_LIMIT_PREFIX = "crcr:rate:"
21+
_IN_PROGRESS_ZSET = "crcr:in_progress"
2122
_cached_client: redis_lib.Redis | None = None
2223
_cached_client_url: str | None = None
2324

@@ -313,9 +314,10 @@ def set_callback_state(
313314
"state": state.value,
314315
"timestamp": timestamp,
315316
}
317+
316318
if payload:
317319
data["payload"] = payload
318-
client.setex(key, config.oot_status_ttl, json.dumps(data))
320+
client.setex(key, config.crcr_status_ttl, json.dumps(data))
319321
logger.info(
320322
"callback state set key=%s state=%s timestamp=%s",
321323
key,

0 commit comments

Comments
 (0)