"dedupe 키는 첫 전송 전에 이미 있어야 해. 그 말은 서버가 아니라 클라이언트가 발급해야 한다는 거고."
왜 ID 가 폰에서 태어나나
재시도를 dedupe 하려면 같은 의도로 하는 시도가 전부 같은 키를 달고 있어야 해. 그럼 그 키가 처음 있어야 하는 시점이 언제일까? 캡처할 때야. 첫 전송 바로 전에. 그 첫 전송이 하필 확인을 못 받고, 그래서 제대로 된 키를 달고 다시 보내야 하는 상황을 만드는 놈일 수 있거든. 서버가 ID 를 발급하면 폰은 응답이 돌아오기 전까진 그걸 못 가져. 그런데 그 응답이 날아가 버리면 재시도할 때 맞춰 볼 키가 없는 거고. 그래서 device turn ID 는 폰에서, 캡처하는 시점에 발급되고, 첫 시도부터 모든 시도에 같이 따라다녀.
키 하나가 canonical 로그에도 남아
device turn ID 는 폰 쪽 사정만이 아냐. 그게 가리키는 턴이랑 나란히 canonical 로그에도 기록돼. 그게 이 키를 로컬 추측이 아니라 진짜 dedupe 키로 만들어. 백엔드가 갖고 있으니까, 이미 끝난 걸로 아는 ID 를 단 요청이 또 오면 반복인 걸 알아보고 일을 다시 하는 대신 있던 결과를 돌려줄 수 있거든. 이 키가 폰이랑 백엔드가 불안한 링크를 사이에 두고 '이거 같은 턴이야' 라고 합의하는 공용어야.
- 발급. 기기에서, 캡처할 때, UUID 로. 아무하고도 상의 안 하고 전역에서 안 겹쳐.
- 보관. 로컬 outbox 에, 그리고 턴이 도착하면 canonical 로그에도.
- 운반. 그 의도로 하는 배달 시도랑 재시도 전부에, 값 하나 안 바뀐 채로.
안 바뀌는 정체성이 트릭 전부야
힘은 전부 그 ID 가 시도가 몇 번이든 안 바뀐다는 데서 나와. 재시도할 때마다 새 ID 를 만들면 목적이 통째로 깨져. 백엔드 눈엔 한 턴을 세 번 시도한 게 아니라 서로 다른 턴 세 개로 보이거든. 규칙은 빡빡해. 의도 하나에 ID 하나, 그 턴이 살아 있는 내내. 캡처할 때 한 번 발급하고, 바로 저장하고, 몇 번을 다시 보내든 새로 만들지 않기. 다음 레슨들이 하는 일이 전부 여기 기대고 있어. 부르기 전에 확인하기, 더블 전송 피하기. 다 이 식별자 하나가 안 변한다는 전제 위에 서 있는 거야.