Skip to content

Commit 0616664

Browse files
authored
more responseive detection of 'rate-limited' crawls: (#3521)
- detect when all crawl pods are in a CrashBackLoop or Terminated status with rate limit exit code (18) and set state to 'rate-limited' - allows for rate limited state to be correctly conveyed in scaled crawls where crawlers are still in exponential backoff loop while redis key has expired
1 parent 728a9e7 commit 0616664

2 files changed

Lines changed: 48 additions & 6 deletions

File tree

backend/btrixcloud/operator/crawls.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,8 @@ def sync_pod_status(
12361236
redis_running = False
12371237
pod_done_count = 0
12381238

1239+
all_crashed = True
1240+
12391241
try:
12401242
for name, pod in pods.items():
12411243
running = False
@@ -1250,22 +1252,39 @@ def sync_pod_status(
12501252
elif phase == "Failed" and pstatus.get("reason") == "Evicted":
12511253
evicted = True
12521254

1253-
status.podStatus[name].evicted = evicted
1255+
pod_status = status.podStatus[name]
1256+
pod_status.evicted = evicted
12541257

12551258
if "containerStatuses" in pstatus:
12561259
cstatus = pstatus["containerStatuses"][0]
12571260

1258-
self.handle_terminated_pod(
1259-
name, role, status, cstatus["state"].get("terminated")
1261+
terminated = cstatus["state"].get("terminated")
1262+
1263+
self.handle_terminated_pod(name, role, status, terminated)
1264+
1265+
waiting = cstatus["state"].get("waiting")
1266+
pod_status.backoffWait = (
1267+
waiting and waiting.get("reason") == "CrashLoopBackOff"
12601268
)
12611269

1270+
if role == "crawler":
1271+
# consider crashed if:
1272+
# - in 'waiting' state with CrashLoopBackOff reason
1273+
# - in 'terminated' state with non-zero exit code (will be brief)
1274+
all_crashed = all_crashed and bool(
1275+
pod_status.backoffWait
1276+
or (terminated and pod_status.exitCode != 0)
1277+
)
1278+
12621279
if role == "crawler":
12631280
crawler_running = crawler_running or running
12641281
if phase == "Succeeded":
12651282
pod_done_count += 1
12661283
elif role == "redis":
12671284
redis_running = redis_running or running
12681285

1286+
status.allCrashed = all_crashed
1287+
12691288
# pylint: disable=broad-except
12701289
except Exception:
12711290
logger.exception(
@@ -1294,13 +1313,14 @@ def handle_terminated_pod(
12941313

12951314
pod_status = status.podStatus[name]
12961315

1316+
# detect reason
1317+
exit_code = terminated.get("exitCode")
1318+
12971319
pod_status.isNewExit = pod_status.exitTime != exit_time
12981320
if pod_status.isNewExit and role == "crawler":
12991321
pod_status.exitTime = exit_time
13001322
status.anyCrawlPodNewExit = True
1301-
1302-
# detect reason
1303-
exit_code = terminated.get("exitCode")
1323+
status.lastCrawlPodExitCode = exit_code
13041324

13051325
if exit_code == 0:
13061326
pod_status.reason = "done"
@@ -1877,6 +1897,21 @@ async def update_crawl_state(
18771897
status.stopReason = await self.is_crawl_stopping(crawl, status, stats)
18781898
status.stopping = status.stopReason is not None
18791899

1900+
# if all crashed and last exit was rate-limit exit code (18),
1901+
# set to rate limited state now and return
1902+
if status.allCrashed and status.lastCrawlPodExitCode == 18:
1903+
if not status.rateLimitedAtTime:
1904+
status.rateLimitedAtTime = date_to_str(dt_now())
1905+
1906+
await self.set_state(
1907+
"rate-limited",
1908+
status,
1909+
crawl,
1910+
allowed_from=RUNNING_STATES,
1911+
)
1912+
status.resync_after = self.fast_retry_secs
1913+
return status
1914+
18801915
# mark crawl as pausing or stopping
18811916
if status.stopping:
18821917
if status.stopReason in PAUSED_STATES:

backend/btrixcloud/operator/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class PodInfo(BaseModel):
159159
signalAtMem: int | None = None
160160

161161
evicted: bool | None = False
162+
backoffWait: bool | None = False
162163

163164
lastWorkers: int | None = 0
164165

@@ -275,6 +276,12 @@ class CrawlStatus(BaseModel):
275276
# any pods exited
276277
anyCrawlPodNewExit: bool | None = Field(default=False, exclude=True)
277278

279+
# exit code of last pod to exit
280+
lastCrawlPodExitCode: int | None = 0
281+
282+
# all running pods have crashed
283+
allCrashed: bool = False
284+
278285
# if status is 'rate-limited', when first became rate-limited
279286
rateLimitedAtTime: str | None = None
280287

0 commit comments

Comments
 (0)