ai-coding-mines목차GitHub

동기 대량 라우트는 호출자 타임아웃에서 터진다

배포 · 인프라

증상

건수가 많은 작업을 한 HTTP 요청 안에서 동기로 처리했더니 응답이 안 돌아온다. 부분 처리분은 커밋됐는데 응답이 없어 진행 상태를 알 수 없다(재시도하면 중복 위험).

타임아웃은 하나가 아니다 — 이게 핵심이다

이 지뢰를 네 번 밟는 동안 매번 더 빡빡한 타임아웃이 하나씩 더 나왔다.

성격
워커 타임아웃내가 정한다. 늘릴 수 있다
외부 스케줄러 타임아웃못 늘린다. 플랫폼 하드 상한이다
항목당 최악 지연외부 의존이라 보장이 없다

건수 캡(limit)은 시간 캡이 아니다. limit=10에 항목당 최악 8초면 80초다. 워커 타임아웃은 안 넘는데 외부 스케줄러의 30초를 넘긴다.

중간 처방과 그 한계 (남겨둘 값어치가 있다)

처음엔 벽시계 예산으로 갔다 — 항목마다 착수 *전에* 경과를 확인하고, 예산에 닿으면 중단하고 {처리분, 잔여, 예산소진}을 200으로 반환. 남은 건 다음 호출이 이어받는다. 한 건씩 잡아 처리·커밋하면 중단 시 미처리 잔재가 0이 된다.

이걸로도 안 됐다. 두 가지 때문이다.

  1. 예산이 22초여도 진행 중인 1건이 초과할 수 있다. 하드 상한 앞에서는 "대체로 안에 든다"가 무의미하다
  2. 한 라우트가 무거운 작업 두 개를 스택하고 있었다. 앞에만 예산을 걸었더니 뒤는 무예산으로 20~40초를 더 썼다. 게다가 뒤 작업이 아예 못 돌아 굶었다 — 외부 스케줄러의 빨강은 어느 홉이 굶었는지 안 알려준다

확정 처방 — 예산 역산이 아니라 즉답

작업 예산 < 스케줄러 간격 < 워커 타임아웃

결과

http=202 · 0.24초. 즉답 설계라 큐 길이와 무관하게 상수 시간이 된다. 하드 상한 대비 여유가 100배 이상이면 그 축은 고민 대상에서 사라진다.

규율

호출자의 타임아웃이 플랫폼 하드 상한이고 작업이 그 안에 안 끝날 수 있으면, 예산으로 깎지 말고 즉답 + 백그라운드 + 멱등 재개 + 중복 가드로 간다. 예산 깎기는 상한을 늘릴 수 있을 때만 유효하다.

상태 저장소를 따로 만들지 않는다

작업 대상 자체를 상태로 쓴다(초안/발행/메타플래그가 곧 진행상태). 별도 잡스토어 없이 무상태 재개가 된다. 작업이 이미 멱등·재개 가능하면 백그라운드 스레드가 고아가 돼도 다음 호출이 이어받는다.

후속 — 할 일이 0일 때의 비용을 먼저 본다

잔여 0인데도 한 틱이 30초 넘게 걸렸다. 원인은 틱이 전체 목록을 매번 두 번 조회하는 것이었다. 할 일이 없어도 그 고정비를 태운다.

→ 수렴 후 즉시 skip하는 완료 캐시, 목록은 틱당 1회만 조회해 공유, 그리고 '대상 0'을 대상 없음(정상) vs 조회 실패(이상) 로 구분해 로그한다.

주기 작업의 튜닝은 고정비를 없앤 뒤에 측정하고 결정한다.