본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

local-first outbox

~12 min · local-first, outbox, offline, state-machine

Level 0표식 없는 길
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"저장은 네 폰에서 일어나. 네트워크는 자르고 다시 부를 수 있는 배달원이야. 네 생각이 살아남을지 정하는 건 절대 아니고."

저장은 로컬이야

현장 캡처를 믿을 수 있게 만드는 invariant가 여기 있어. breadcrumb은 어떤 네트워크 sync보다 먼저, 기기에, 로컬로 커밋된다. 저장을 탭하는 순간 생각은 로컬 outbox에 durable하고, 그다음에야 엔진이 Office로 push를 시도해. 죽은 호텔 네트워크든, 비행기 모드든, 닿지 않는 Pippa든 기억을 앗아갈 수 없다는 뜻이야. Office 연결도 Pippa도 저장 임계경로에 절대 없어. 네트워크가 할 일은 이미 안전히 저장된 걸 배달하는 거지, 저장하는 그것 자체가 되는 게 아냐.

outbox state machine

캡처된 breadcrumb은 저마다 명시적 state를 지나. LOCAL_ONLY, QUEUED, SYNCING, SYNCED, FAILED_NEEDS_ATTENTION. 결정적 규칙은 로컬 payload가 idempotent한 서버 승인 전엔 절대 삭제 안 된다는 거야. sync 실패한 crumb은 사라지지도, 조용히 중복 retry하지도 않아. 해결될 때까지 눈에 보이는 failed state에 앉아 있어. 그리고 스트림이 항상 unsynced 수를 드러내니까, PWA 저장이 최종 아카이브가 아니라 staging 영역이라는 걸 한눈에 봐. 아무것도 조용히 안 버려지고, 아무것도 조용히 안 중복돼.

왜 현장에선 idempotency가 중요해

현장 네트워크는 느리기만 한 게 아냐. 모호해. 요청이 나가고, 연결이 죽고, 서버가 받았는지 진짜 몰라. 순진한 수정인 맹목 retry는 중복을 만들어. 첫 게 실제로 도착했으면 같은 crumb 사본이 두 개 되는 거지. Waystone은 crumb마다 안정된 기기-생성 정체성을 줘서, retry가 idempotent야. 서버가 같은 crumb으로 알아보고 두 번째를 안 만들어. 이게 나쁜 연결 뒤에 낫는 outbox랑, 신호 끊길 때마다 기억을 조용히 불리는 것의 차이야.

local-first는 성능 트릭이 아냐. 신뢰 보장이야. 저장이 로컬이고 sync가 idempotent면, 나쁜 네트워크가 할 수 있는 최악은 crumb을 늦추는 것뿐이야. 절대 잃거나 중복 안 해. 바로 네트워크가 실패하는 데서 쓰이는 기억 엔진한텐, 그 보장이 곧 제품이야.

Code

outbox 라이프사이클·text
저장 탭
   |
   v
LOCAL_ONLY  --queue-->  QUEUED  --push-->  SYNCING
   ^                                          |  |
   |                                   (ack)  |  |  (error)
   |                                          v  v
   |                                     SYNCED  FAILED_NEEDS_ATTENTION
   |                                                    |
   '------------------ retry (idempotent) ------------'

# 로컬 payload 는 idempotent ack 전에 절대 삭제 안 됨.
# 안정된 crumb id => retry 가 중복 못 만듦.
# 스트림이 unsynced 수 표시: 아카이브가 아니라 staging.

External links

Exercise

빠른 캡처에 기대는 앱을 테스트해봐. 비행기 모드 켜고, 뭔가 저장하고, 무슨 일이 일어나는지 봐. 로컬로 저장하고 나중에 sync했어, 아니면 실패하거나, 뱅뱅 돌거나, 입력을 잃었어? 이제 다시 연결하고 중복을 봐. 오프라인 저장 못 하거나 재연결에 중복하는 앱은 여행 도구가 제일 많이 쓰이는 바로 거기서 널 실망시켜.
Hint
비행기 모드에서 두 테스트를 다 해봐. 하나, 네트워크가 전혀 없어도 저장이 살아남아? 둘, 다시 연결하면 사본이 하나야 둘이야? 둘 다 통과면 local-first에 idempotent sync야. 하나라도 실패면 네트워크가 네 저장 임계경로에 있는 거고, 거긴 있으면 안 될 곳이야.

Progress

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

댓글 0

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

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