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

네트워크는 저장이 아냐

~12 min · local-first, critical-path, durability, anti-pattern

Level 0신호 없음
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"전송 버튼이랑 저장 버튼은 똑같이 생겼어. 둘을 같은 동작에 묶는 게, 천 개의 잃어버린 메시지 뒤에 있는 버그야."

잃어버린 입력의 심장에 있는 혼동

'앱이 내 메시지 먹었어' 이야기는 거의 다 뿌리가 같아. 앱이 전송저장으로 다룬 거야. 타이핑하고, 버튼 누르고, 네 말이 존재하는 유일한 곳은 네트워크 위를 날아가는 중이었어. 요청이 실패하면 — 터널, 타임아웃, 백그라운드로 밀린 앱 — 돌아갈 데가 없었어. 먼저 적어둔 게 아무것도 없었으니까.

캡처 먼저는 이걸 거부해. 하나처럼 보이는 동작을 정해진 순서로 둘로 쪼개: 로컬에 커밋, 그다음 운송. 저장은 로컬의, 동기처럼 느껴지는 내구성 있는 쓰기야. 전송은 이미 저장된 걸 읽는 별개의, 재시도 가능한 네트워크 시도고. 네트워크는 저장 경로에 절대 안 껴 — 배달 경로에만 껴.

임계 저장 경로

사용자 의도랑 내구성 사이에 뭐가 있냐에 대한 규칙이라고 생각해. 임계 저장 경로(critical save path)는 사용자 입력이 안전해지려면 반드시 성공해야 하는 모든 단계야. 네트워크가 그 경로에 있으면, 내구성은 연결만큼만 믿을 만해 — 기차에선 동전 던지기지. 캡처 먼저는 네트워크를 임계 저장 경로에서 완전히 :

  • 사용자 제출 → 로컬 내구 저장소에 쓰기 → 끝, 입력은 안전.
  • 별개로, sync 워커가 저장소를 읽어서 배달을 시도해. 지금, 나중에, 또는 재시작 후에.

어떤 패킷이든 폰을 떠날 때쯤엔, 질문은 이미 잃을 수 없어. 배달은 실컷 실패해도 돼. 네 말을 데려가진 못해.

순서가 트릭 전부

마법은 전부 순서에 있어. await commitLocally()fetch() 를 부르기 전에 끝나야 해. 뒤집거나 — 같이 돌리고 잘되길 바라면 — 넌 조용히 네트워크를 저장 경로에 다시 갖다놓은 거야. '로컬 우선' 클라이언트가 실은 로컬 우선이 아닌 제일 흔한 방식이 이거야: 로컬 쓰기는 있는데, 전송 뒤에, 영영 안 올지도 모를 성공의 캐시로 일어나.

Code

맞는 순서 vs 틀린 순서·typescript
// 틀림: 네트워크가 저장 경로에 있음.
async function submitWrong(turn: PippaGoTurn) {
  const res = await fetch("/api/ask", { method: "POST", body: encode(turn) });
  await saveLocally(turn); // 너무 늦음 — fetch 가 던지면 여기 못 옴
}

// 맞음: 로컬에 먼저 커밋, 그다음 운송.
async function submit(turn: PippaGoTurn) {
  await commitLocally(turn);        // 입력은 이제 잃을 수 없음
  turn.syncStatus = "pending";
  await enqueueForDelivery(turn);   // 지금/나중/재시작 후 실행 가능
}

// 순서는 스타일 선택이 아냐. '내구 후 배달' 이랑
// '배달되거나 잃거나' 의 차이야.

External links

Exercise

메시지 제출을 두 방식으로 의사코드로 써봐: 하나는 로컬 저장이 네트워크 호출 뒤에, 하나는 앞에. 네트워크 호출이 예외를 던질 때 각 버전에서 사용자한테 뭐가 남는지 추적해. 그 차이 — '아무것도 없음' vs '내구성 있는 pending 메시지' — 가 캡처 먼저의 가치 전부야, 다섯 줄로.
Hint
네트워크-뒤 버전에선 예외가 저장을 통째로 건너뛰어. 네트워크-앞 버전에선 저장이 이미 커밋됐으니, 예외는 메시지를 재시도 가능한 'failed' 상태로만 남겨. 같은 기능, 반대의 신뢰성.

Progress

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

댓글 0

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

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