3.3 KiB
kind, slug, title, topic, topicName, project, status, sourceRevision, rootTreeNode, source
| kind | slug | title | topic | topicName | project | status | sourceRevision | rootTreeNode | source | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CASE | a-mark-that-meant-seen-not-projected | 「본 적 있는 위치」를 「투영이 끝난 위치」로 쓴 mark 가 재전달된 이벤트를 삼켰다 | owner-safe-state-machines | owner-safe 상태 기계 — 소유권을 SQL에 적기 | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | case:a-mark-that-meant-seen-not-projected |
|
「본 적 있는 위치」를 「투영이 끝난 위치」로 쓴 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
재현 조건
- 이벤트 위치 mark가 갱신되는 시점과 projection 반영 시점을 분리해 확인한다.
- mark 전진 뒤 projection 완료 전에 worker를 중단한다.
- 다른 worker가 같은 stream을 resume했을 때 해당 이벤트가 다시 처리되는지 확인한다.
- 이번 검토에서는 기존 SSOT probe 결과만 사용했고 새 실행은 하지 않았다.
본문
필요한 상태는 세 개다
아직 보지 않은 위치, 본 적은 있지만 projection이 끝나지 않은 위치, projection까지 완료한 위치를 구분해야 한다.
두 상태만 두고 “봤다”를 “끝났다”로 사용하면 failover 중간 상태를 표현할 수 없다.
mark는 완료 뒤에 전진한다
projection 반영과 mark 갱신이 하나의 owner-safe 전이로 묶이거나, 적어도 완료가 증명된 뒤 mark를 갱신해야 한다. 새 worker는 완료 mark만 resume 기준으로 사용한다.
확인하지 못한 것
기존 probe는 단일 worker의 한 번 failover다. 반복 failover와 다중 worker에서의 손실 폭은 측정하지 않았다.