응답 매칭 규칙 (클라이언트 구현)
응답 순서가 요청 순서와 다를 수 있으므로(대기에 들어간 획득의 응답은 차례가 온 시점에 도착), 클라이언트는 다음 규칙으로 응답을 요청에 짝지어야 합니다 — 한 연결에 섞여 오는 응답들을 각 요청으로 나눠 주는 디멀티플렉스(demultiplex) 규칙입니다.
| 규칙 | 내용 |
|---|---|
| 매칭 키 | 에코된 (op, 키, 식별자). 획득 계열(A/T/B)은 요청의 owner와, 해제 계열(R/N)은 요청의 token과 매칭 |
| 동일 (op, 키) 다중 요청 | FIFO를 가정하면 안 됨 — 반드시 식별자로 특정. 아래 설명 참고 |
| 등록 시점 | 요청을 전송하기 전에 대기자를 등록 (응답이 먼저 도착하는 레이스 방지) |
N/T 처리 | 에러가 아닌 값("없었음"/"타임아웃")으로 반환 |
B 처리 | 대기열/서버 capacity 포화로 이번 요청은 확정 미획득 — 즉시 Busy 반환, 내부 자동 재전송 없음 |
M 처리 | allowlist의 주소만 리더 힌트로 저장하고 그 연결을 닫음. owner/key가 없으므로 송신된 pending에 대응시키지 않음 |
L 처리 | 리더 힌트만 갱신하고 연결은 유지 — 요청 응답이 아니라 서버 발신 통지 |
E no_leader / E not_active / E auth_failed | 연결을 닫고 오류 종류에 맞는 backoff 적용 (no_leader는 리더 힌트도 무효화) |
그 외 E/malformed/oversized/알 수 없는 응답 | 상관시킬 수 없으므로 connection-fatal. 이미 전송된 acquire는 Indeterminate |
| 대기자 없는 응답 | protocol/session 불일치로 보고 연결 종료. A라면 이미 아는 exact token을 reserved release lane에 전달 |
FIFO가 아니라 식별자로 매칭해야 하는 이유
같은 키라도 즉시 성공한 요청, 대기 중인 요청, B로 거절된 요청의 응답 시점이 다릅니다. 연결에는 여러 key의 요청도 함께 파이프라인되므로 응답 순서는 요청 순서와 달라질 수 있습니다. FIFO로 매칭하지 말고 반드시 에코된 식별자와 op, key를 모두 확인하세요.
중단된 요청과 고아 락
중단한 요청이 사실은 서버에서 이미 발급된 획득이었다면 그 락은 서버에 남을 수 있습니다. 요청 바이트를 하나라도 보낸 뒤 성공/미획득 응답을 확인하지 못한 결과는 Indeterminate입니다. 같은 owner로 상태를 조회하듯 A를 재전송하면 안 됩니다. client가 token을 이미 파싱한 경우에만 exact-token R을 best-effort로 보내고, token을 모르는 grant는 lease 만료가 회수합니다.
전송 뒤 취소나 framing 오류에서 연결을 닫아야 하는 이유도 여기 있습니다. 연결을 유지한 채 진행 중 요청만 버리면, 이미 발급된 획득의 응답이 갈 곳을 잃어 서버만 락을 아는 상태가 됩니다. 다만 socket close만으로 이미 commit된 grant가 반드시 반납됐다고 추정해서는 안 됩니다. client가 token을 파싱한 경우 exact-token R을 보내고, 모르는 경우에는 lease 만료까지 Indeterminate로 남습니다.