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

하나의 aggregate: 질문 + 이미지 함께

~12 min · aggregate, atomicity, consistency, intent

Level 0신호 없음
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"이미지 없는 질문은 다른 질문이야. 따로 저장될 수 있으면, 따로 망가질 수 있어."

반만 저장된 질문

질문이랑 이미지를 독립된 두 쓰기로 캡처한다고 상상해봐. 텍스트가 저장되고, 그다음 이미지 blob 이 쓰이기 전에 앱이 죽어. 이제 outbox 엔 '이 중에 뭐가 더 선명해?' 가 이미지 없이 들어있어. 마침내 동기화되면, Pippa 는 말 그대로 답할 수 없는 질문을 받아 — 가리키는 대상이 사라졌으니까. 사용자 의도가 조용히 망가진 거야. 전부를 잃어서가 아니라, 나눌 수 없는 하나의 일부를 잃어서.

캡처 먼저는 질문이랑 모든 첨부를 하나의 aggregate 로 다뤄서 이걸 고쳐: 완전히 쓰이거나 아예 안 쓰이는 한 단위. 텍스트는 있는데 이미지는 없는 유효한 중간 상태 같은 건 없어. 턴 전체가 내구성 있거나, 아니면 제출이 아직 안 일어난 거야.

aggregate 는 하나의 일관성 경계

이 단어는 도메인 모델링에서 왔어. aggregate 는 내부적으로 일관돼야 하고 항상 전체로만 수정되는 데이터 뭉치야. Pippa Go 턴의 일관성 규칙은 단순하고 엄격해 — 질문이랑 그게 참조하는 이미지는 떨어지면 무의미해. 그래서 하나의 경계를 공유해:

  • 커밋 하나가 질문 텍스트 모든 이미지 blob 이랑 첨부 참조를 함께 써.
  • 그 커밋이 완료 못 하면, 아무것도 없음으로 롤백돼 — 고아 텍스트도, 고아 blob 도 없이.
  • 아래서, 배달이랑 재시도는 항상 aggregate 전체를 옮기지 조각을 옮기지 않아.

왜 원자성이 '그냥 다시 붙이기'를 이기나

솔깃한 지름길은 조각들을 따로 저장하고 '나중에 화해시키기' 야 — 이미지가 없으면 다시 붙이기. 근데 화해가 버그의 번식지야: 어느 이미지? 어느 질문에? 두 턴이 동시에 날아가는 중이면? 원자적 aggregate 는 이 문제 부류를 통째로 삭제해. 화해가 없어, 화해시킬 불일치의 순간이 애초에 없었으니까. 쓰기 하나, 경계 하나, 의도 하나 — 사용자가 제출 누른 순간부터 통째로 지켜져.

Code

턴 전체를 원자적 쓰기 하나로·typescript
// 턴이랑 이미지 blob 들이 IndexedDB 트랜잭션 하나로 커밋돼.
async function commitLocally(turn: PippaGoTurn, blobs: Map<string, Blob>) {
  const tx = db.transaction(["turns", "blobs"], "readwrite");
  // 전부-아니면-전무: 어느 put() 이든 실패하면 tx 전체가 abort 되고 롤백돼.
  tx.objectStore("turns").put(turn);
  for (const [localId, blob] of blobs) {
    tx.objectStore("blobs").put({ localId, blob });
  }
  await tx.done; // 전부 함께 커밋됐을 때만 resolve
}

// turn.attachments 가 저장소에 없는 blob 을 참조하는 상태는 없어.
// aggregate 는 일관되거나 부재하거나.

External links

Exercise

이미지 붙은 질문의 '반만 저장된' 실패 모드 세 개를 적어: 이미지 없는 텍스트, 텍스트 없는 이미지, 엉뚱한 질문에 붙은 이미지. 각각에 대해 Pippa 가 뭘 받고 왜 답이 틀릴지 설명해. 그다음, 턴 전체를 원자적으로 커밋하는 게 어떻게 세 개를 '다뤄지는' 게 아니라 '불가능하게' 만드는지 한 문장으로 설명해.
Hint
세 실패 모드 다 aggregate 의 일부가 나머지 없이 존재하는 순간을 필요로 해. 원자적 커밋엔 그런 순간이 없어 — 중간 상태가 그냥 존재하지 않으니, 셋 중 어느 것도 일어날 수 없어.

Progress

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

댓글 0

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

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