LabHub

큐와 비동기 API · 비동기 API 설계(202 Accepted·폴링·웹훅) · 실습

작업 제출과 상태 폴링 API 만들기

LabHub 에서 이어서 보기

목표

202 Accepted 로 시작하는 비동기 API 의 전체 계약 — 접수, 상태 조회, 폴링 조절, 멱등 제출, 완료 통보 — 를 직접 구현한다.

왜 중요한가

30초 걸리는 작업을 동기 API 로 만들면 세 가지가 동시에 깨집니다. 로드밸런서 유휴 타임아웃에 걸리고, 클라이언트 재시도가 같은 작업을 두 번 돌리고, 워커가 30초씩 묶입니다. 비동기 API 는 이것을 접수와 확인으로 나눕니다. 그런데 202 만 돌려주고 끝내는 API 가 의외로 많습니다. 클라이언트는 결과를 어디서 봐야 할지 모르고, 얼마나 기다려야 하는지 모르고, 재시도해도 되는지 모릅니다. 이 실습은 그 계약의 빠진 조각들을 하나씩 채웁니다 — Location 헤더, 상태 어휘, Retry-After, 멱등성 키, 그리고 웹훅입니다. 이것들을 다 갖추면 그때부터 클라이언트가 안심하고 재시도할 수 있습니다.

단계

1. /root/aj/api.py 를 127.0.0.1:8140 에 띄운다. POST /jobs{"n":5} 를 받아 큐 q:jobs2 에 넣는다.
2. POST /jobs 응답은 202 이고 Location: /jobs/<job_id> 헤더와 본문 {"job_id":"...","status":"queued"} 를 준다.
3. GET /jobs/<job_id> 는 200 과 status 를 준다. 값은 queued, running, succeeded, failed 중 하나이다. 없는 id 는 404 이다.
4. /root/aj/worker.py 는 큐에서 꺼내 상태를 running 으로 바꾸고 처리 후 succeeded 로 바꾼다.
5. 완료된 작업 조회 응답에 result 키가 있어야 한다. queued 상태에서는 result 키가 없어야 한다.
6. queued 또는 running 상태 응답에는 Retry-After 헤더가 정수 초로 붙고, succeeded 응답에는 붙지 않는다.
7. 같은 Idempotency-Key 로 두 번 제출하면 같은 job_id 를 돌려주고 큐에는 1건만 들어간다.
8. /opt/app/hooksink.py 를 127.0.0.1:8141 에 띄운다. 제출 시 callback_url 을 함께 받아 완료 시 그 주소로 POST 한다. /root/aj/hook.logjob_idstatus=succeeded 가 기록된다.

참고

단계 8개

  1. 작업 제출 API 띄우기
  2. 202 와 Location 헤더 돌려주기
  3. 상태 조회 엔드포인트 만들기
  4. 워커가 상태를 전이시키기
  5. 완료 후 결과 담기
  6. 폴링 간격 제안하기
  7. 제출을 멱등하게 만들기
  8. 완료 웹훅 보내기