C.W.K.
Stream
Lesson 04 of 04 · published

끊김은 상태를 바꾸지 입력을 안 바꿔

~11 min · state-machine, immutability, resilience, status

Level 0신호 없음
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"payload 는 제출 누른 순간 얼어. 그 뒤로 세상이 건드릴 수 있는 건 상태 플래그 하나뿐이야."

한 턴 안의 두 종류 상태

캡처된 턴엔 아주 다른 두 종류의 상태가 있고, 그 둘을 분리하는 게 끊김을 무해하게 만들어:

  • payload — 질문 텍스트랑 이미지 blob. 캡처 순간부터 불변이야. 네트워크 이벤트, 앱 죽음, 재시도 뭐도 이걸 다시 쓰지 않아.
  • sync 상태pending → sending → answered | failed. 이게 유일한 가변 부분이고, 모든 전이가 내구성 있는 쓰기야.

턴을 이렇게 보면, '전송 도중 앱이 죽으면 어떻게 돼?' 는 지루하고 올바른 답을 가져: payload 는 손 안 탐(얼었고 내구성 있었으니), 상태는 여전히 sending 이거나 이미 failed 로 뒤집힘. 어느 쪽이든, 다음 실행이 뭘 할지 정확히 알아. 끊김은 데이터 손실 이벤트가 아냐. 상태 전이 이벤트야.

왜 payload 의 불변성이 중요한가

끊김이 payload 를 바꿀 수 있으면, 모든 실패가 잠재적 손상이야. 질문을 다시 인코딩하는 재시도, 반쯤 쓰인 blob 을 다시 읽는 백그라운드 sync, 두 필드 업데이트 사이의 크래시 — 각각이 사용자의 실제 말을 동의 없이 바꾸는 통로가 돼. payload 를 캡처 때 얼리고 상태만 전이시키면, 거대한 실패 모드 공간을 하나의 작고 잘 이해된 상태 기계로 접어버려. 무서운 질문 '그 크래시 후에 내 데이터 아직 맞아?' 가 '어느 상태에 있어?' 가 돼 — 답이 넷뿐이고, 다 안전한 질문.

상태 기계가 곧 계약

상태 전이를 명시적으로 설계하면 견고함이 따라와. payload 를 삭제하는 전이는 없어. '잃음'을 뜻하는 상태도 없어. 최악의 상태는 failed 인데, 그것도 여전히 턴 전체를 쥐고 그냥 재시도를 청해. 그게 보이게 된 약속이야: 끊긴 턴은 절대 사라지지 않아 — 그냥 작고 안전한 지도 어딘가에서 기다릴 뿐이야.

Code

payload 는 얼고; 상태만 전이·typescript
// payload 는 캡처 후 readonly. 끊김은 상태만 건드림.
type CapturedTurn = {
  readonly deviceTurnId: string;
  readonly question: string;          // 제출 때 얼음
  readonly attachmentIds: string[];   // 제출 때 얼음
  syncStatus: "pending" | "sending" | "answered" | "failed"; // 유일한 손잡이
  answer?: string;                    // 성공 시 한 번 설정
};

// 합법 전이는 작고 안전한 지도를 이뤄:
//   pending  -> sending
//   sending  -> answered | failed
//   failed   -> sending        (재시도)
// 어느 전이도 question/attachmentIds 를 삭제 안 해. '잃음'은 상태가 아냐.

External links

Exercise

캡처된 턴의 전체 상태 기계를 그려: 모든 상태, 모든 합법 전이, 각각의 트리거. 그다음 payload 를 잃는 전이를 추가해보려 해봐 — 그리고 못 한다는 걸 알아채. 안전한 상태 중 뭐도 삭제를 가리키지 않으니까. 마지막으로 어느 전이가 내구성 있는 쓰기인지 표시해(전부야). 그 다이어그램이 캡처 먼저 약속을 한 그림에 담은 거야.
Hint
상태: pending, sending, answered, failed. 트리거: 제출, drain 시작, 배달 성공, 배달 에러, 재시도. 일부러 'lost' 노드가 없어 — 그 노드의 부재가 핵심 전부야.

Progress

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

댓글 0

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

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