--- kind: CASE slug: a-mark-that-meant-seen-not-projected title: 「본 적 있는 위치」를 「투영이 끝난 위치」로 쓴 mark 가 재전달된 이벤트를 삼켰다 topic: owner-safe-state-machines topicName: owner-safe 상태 기계 — 소유권을 SQL에 적기 project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:a-mark-that-meant-seen-not-projected source: - final/document.md#8-1 - final/document.md#a06 - final/document.md#4-2 - final/document.md#8-1 항목 9 - final/document.md#a06 §67 --- # 「본 적 있는 위치」를 「투영이 끝난 위치」로 쓴 mark 가 재전달된 이벤트를 삼켰다 이벤트 위치를 “관측했다”는 시점에 mark를 전진시키면 projection이 끝나기 전에 failover가 발생했을 때 재전달 이벤트를 이미 처리한 것으로 오인할 수 있다. 기존 분석은 한 번의 failover probe에서 이 손실 경로를 재현했다. ## 관계 - **CAS tuple과 update count** 상태 전이가 완료됐다는 조건을 owner와 revision으로 함께 검사하는 개념이다. - **lease에는 owner가 있어야 한다** worker가 바뀌는 경계에서 이전 소유자의 진행 상태를 그대로 신뢰하지 않는 사례다. ## 문제 mark가 이벤트를 읽은 직후 전진하고 실제 projection 반영은 그 뒤에 실행되면 두 상태 사이에 공백이 생긴다. worker가 그 공백에서 중단되고 다른 worker가 mark부터 읽으면, 새 worker는 해당 위치를 이미 완료한 것으로 판단해 이벤트를 건너뛸 수 있다. ## 결론 “마지막으로 본 위치”와 “projection을 완료한 위치”는 같은 상태가 아니다. 완료 mark는 projection이 성공적으로 반영된 뒤에만 전진해야 한다. 기존 probe는 worker 하나와 한 번의 평범한 failover만 다뤘다. 여러 worker나 반복 resume에서 손실 폭이 어떻게 달라지는지는 확인하지 않았다. ## 검증 환경 sourceRevision : 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 확인 방식 : SSOT에 기록된 failover probe 결과 현재 source repository 재대조 : UNVERIFIABLE ## 재현 조건 1. 이벤트 위치 mark가 갱신되는 시점과 projection 반영 시점을 분리해 확인한다. 2. mark 전진 뒤 projection 완료 전에 worker를 중단한다. 3. 다른 worker가 같은 stream을 resume했을 때 해당 이벤트가 다시 처리되는지 확인한다. 4. 이번 검토에서는 기존 SSOT probe 결과만 사용했고 새 실행은 하지 않았다. ## 본문 ## 필요한 상태는 세 개다 아직 보지 않은 위치, 본 적은 있지만 projection이 끝나지 않은 위치, projection까지 완료한 위치를 구분해야 한다. 두 상태만 두고 “봤다”를 “끝났다”로 사용하면 failover 중간 상태를 표현할 수 없다. ## mark는 완료 뒤에 전진한다 projection 반영과 mark 갱신이 하나의 owner-safe 전이로 묶이거나, 적어도 완료가 증명된 뒤 mark를 갱신해야 한다. 새 worker는 완료 mark만 resume 기준으로 사용한다. ## 확인하지 못한 것 기존 probe는 단일 worker의 한 번 failover다. 반복 failover와 다중 worker에서의 손실 폭은 측정하지 않았다.