현재 테스트 중입니다: 완료되면 GitHub 코드를 오픈할 예정입니다.

A · 획득

구조refresh

락 획득 요청입니다. lease는 임대(초) — 클라이언트가 반납하지 않고 죽어도 이 시간이 지나면 서버가 회수하는 안전망입니다. wait는 획득 대기 상한(초)으로, 0이면 대기열에 들어가지 않고 한 번만 즉시 시도합니다. 무한 대기는 없습니다. 응답은 성공 시 획득됨 A, 대기 실패 시 타임아웃 T, 대기열이 가득 찼으면 사용 중 B입니다.

owner — 응답 상관 식별자

owner획득 시도 하나의 응답을 찾는 식별자로, 클라이언트가 호출마다 새로 만듭니다. 서버는 응답의 A·T·B에 같은 값을 에코하므로 파이프라인에서 어느 요청의 응답인지 구분할 수 있습니다.

owner는 락 권한이나 펜싱 토큰이 아닙니다. 같은 key와 owner를 다시 보내도 active token을 돌려받거나 lease를 갱신하지 않습니다. 요청 바이트를 하나라도 보낸 뒤 응답을 확인하지 못하면 클라이언트는 같은 owner로 자동 재전송하지 않고 결과를 Indeterminate로 처리해야 합니다. 이때 critical section에 들어가면 안 되며, 관찰하지 못한 grant는 최장 lease 안에 서버가 회수합니다.

공식 클라이언트는 caller의 정규화된 wait로 monotonic 전체 deadline을 한 번 만들고, 확정적으로 아직 보내지 않은 retry에도 그 deadline과 owner를 유지합니다. writer는 송신 직전에 남은 시간을 올림해 wire wait를 다시 계산하므로 늦은 연결이 server 대기를 새로 255초 시작하게 만들지 않습니다. 원래 wait=0도 wire에서는 계속 즉시 시도이며, 별도 5초 transport deadline 안에서 확정 미송신인 경우에만 같은 owner로 연결 선택·재시도할 수 있습니다. 실제 server-side 시도는 여전히 한 번뿐입니다. 전체 deadline을 넘은 queued 요청은 보내지 않으며, 이미 보냈을 가능성이 있으면 해당 session을 닫고 Indeterminate로 끝냅니다. deadline 직전 이미 상관된 A를 Ticket 전달 단계에서 늦게 발견했다면 session을 닫을 필요는 없지만, exact token 보상 release를 예약하고 Indeterminate를 반환합니다. 이미 상관된 TB는 각각 확정 timeout과 확정 busy로 유지합니다.

바이트 표기: op는 ASCII 문자, wait·lease는 바이너리(u8), owner는 바이너리 (u64, 빅엔디안), key는 UTF-8 텍스트(가변, 구조에서 N)입니다. 마지막 \n0A. 고정 헤더는 이진 값이라 0x0A를 포함할 수 있으니, 개행을 찾기 전에 바이트 수로 먼저 소비해야 합니다.

흐름

클라이언트
서버
A · 획득 (key · wait · lease · owner)
비어 있는 키 → 즉시 발급
A · 획득됨 (token)
점유 중 + wait>0 → FIFO 대기열에서 차례 대기
차례가 오면 A · 획득됨 (token)
wait 초과 → T · 타임아웃
wait=0 + 점유 중 → T · 즉시 미획득
대기열/서버 용량 포화 → B · 사용 중
요청응답

키 상태별 동작의 전체 규칙은 요청 × 키 상태 매트릭스를 참고하세요.