본문 바로가기
C.W.K.
Stream
Lesson 03 of 04 · published

어떤 모델 호출 전에도 완료 / 대기 / 모름을 확인

~12 min · retry-logic, state-check, guard, dedupe

Level 0신호 없음
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"안전한 재시도는 '다시 보낼까?' 를 묻지 않아. '이 턴한테 이미 무슨 일이 있었지?' 를 묻지. 그리고 답은 꽤 자주 '더 할 거 없음' 이야."

재시도는 재전송이 아니라 질문이야

순진한 재시도는 그냥 요청을 다시 쏴. 안전한 재시도는 device turn ID 로 턴 상태부터 확인하고, 호출할 명분이 진짜 있을 때만 모델을 불러. 배달이 적어도 한 번이니까, 재시도가 사실은 이미 멀쩡히 성공한 걸 또 보내는 걸 수도 있거든. 답은 있고 확인만 못 받은 거지. 무작정 다시 보내면 진짜 일을 한 번 더 하게 되고. 그래서 모델을 부르기 전에 클라이언트는 턴을 세 상태 중 하나로 확정해.

  • 완료. 백엔드가 이 device turn ID 에 대한 답을 이미 갖고 있어. 모델 부르지 말고 그 답을 가져다 보여줘.
  • 대기. 턴은 알고 있고 처리 중이거나 큐에 있는데 아직 답이 안 나왔어. 다시 부르지 말고 기다려서 결판나게 둬.
  • 모름. 백엔드에 이 ID 기록이 아예 없어. 모델을 불러도 되는 유일한 상태야. 그 의도가 진짜로 실행이 안 된 거니까.

가드가 중복을 no-op 으로 바꿔

이 확인이 정확히 한 번 의도를 실제로 만들어내는 장치야. 지난 레슨의 dedupe 키가 안 바뀌는 정체성을 주고, 이 가드가 그걸 쓰는 거지. 재시도는 전부 같은 게이트를 지나. 상태를 확정하고, 그다음에 갈라져. 완료랑 대기는 둘 다 새 일 없이 거기서 끊겨. 적어도 한 번 배달을 무해하게 만들어 주는 no-op 이지. 모름일 때만 모델까지 가고. 이 가드가 클라이언트 쪽에서 중복을 다 흡수하니까 선 위에서 중복을 막을 필요가 없어.

확인이 어디 있느냐가 중요해

가드는 모델 호출 뒤가 아니라 앞에 둬. 모델 부르고 나서 도는 확인은 아끼려던 비용을 이미 다 쓴 뒤야. 맞는 모양은 이래. 재시도할 때 ID 로 턴 상태를 백엔드한테 물어봐. 아니면 거기서 동기화돼 온 로컬 기록을 읽든가. 그 답에 따라 갈라지고. 모름 쪽으로 갈렸을 때만 모델을 불러. 몇 줄 안 되는데, 그 몇 줄이 안전하게 재시도하는 클라이언트랑 소리 없이 모든 걸 두 번 하는 클라이언트를 가르는 전부야.

Code

상태부터 확정하고, 모름일 때만 모델 호출·typescript
async function retry(turn: PippaGoTurn) {
  const state = await resolveTurnState(turn.deviceTurnId); // dedupe 키로 물음

  switch (state.kind) {
    case "completed":
      return showAnswer(state.answer);        // 이미 됨 — 모델 호출 없음
    case "pending":
      return showWaiting();                    // 진행 중 — 모델 호출 없음
    case "unknown":
      return materializeFromCanonical(turn);   // 여기서만 모델을 부름
  }
}

// 모델 호출은 가드 뒤에 앉지, 절대 앞에 안 앉아.
// 'completed' 랑 'pending' 이 재시도를 안전하게 만드는 no-op 이야.

External links

Exercise

세 갈래 재시도 가드를 의사코드로 써 봐. device turn ID 로 상태를 확정하고, 완료 / 대기 / 모름 으로 갈라지는 구조. 그다음 네가 썼거나 본 진짜 재시도 코드를 뜯어봐. 상태를 먼저 확인해? 아니면 그냥 다시 보내? 그냥 보내는 쪽이면, 적어도 한 번 배달이 언젠가 일으킬 이중 행동을 구체적으로 적고, 그걸 막을 가드를 어디에 끼울지 써.
Hint
현장에서 보는 재시도 코드는 대부분 backoff 타이머 하나 붙은 맨몸 재전송이야. 상태 확인 같은 건 아예 없고. 첫 ack 이 떨어지기 전까진 잘 굴러가다가 그 뒤로 소리 없이 두 번씩 행동해. 해법은 늘 같아. 부르기 전에 dedupe 키로 상태를 확정하고, 완료랑 대기는 아무것도 안 하게 두는 거.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.