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

필드 제약과 값 범위

요청 필드 (C→S)

필드타입유효 범위의미위반 시
opASCII 1BA(0x41) · R(0x52)요청 종류E bad_op
waitu80 ~ 255 (초)0은 queue 없는 즉시 시도, 1..255는 획득 대기 상한— (타입상 항상 유효)
leaseu81 ~ 250 (초)임대. 0, 251..255는 거부/reservedE bad_lease
owneru64 BE0 ~ 2^64-1 전체획득 시도 식별자 (클라이언트 생성)— (서버가 검사하지 않음)
tokenu64 BE서버가 발급한 값반납 대상 지정 (R 전용)불일치 시 N
keyUTF-81 ~ 128 바이트락 이름. 스페이스(0x20)·개행(0x0A) 불가E bad_key
  • 무한 wait/lease는 없습니다. 공식 클라이언트는 초 미만 값을 올림한 뒤 범위를 검사하며, 범위를 넘으면 clamp하거나 전송하지 않고 명시적 입력 오류를 반환합니다. 기본 lease는 30초입니다.
  • 공식 client API의 wait는 호출 시작부터 local queue, 미송신 연결 재시도, write와 응답까지를 포함한 전체 acquire 상한입니다. monotonic operation deadline을 한 번만 만들고 writer가 실제 송신 직전에 남은 시간을 u8 초로 올림해 frame의 wait에 넣습니다. 따라서 연결이 늦게 살아나거나 확정 미송신 failover가 일어나도 server wait가 처음부터 다시 시작되지 않습니다. deadline 당시 아직 queue에 있으면 확정 미송신 timeout, 한 바이트라도 보냈을 수 있으면 정확한 해당 session을 닫고 Indeterminate입니다. 원래 wait=0만 wire 0을 사용하며, 이 즉시 시도에도 멈춘 transport를 무한히 기다리지 않는 별도의 5초 I/O deadline이 있습니다. 그 안에서 확정 미송신이면 같은 owner로 재시도할 수 있습니다. 이는 server-side 시도가 아직 일어나지 않은 것이므로 server queue 대기를 허용하는 뜻이 아니며, 한 바이트라도 송신됐을 가능성이 생기면 재전송하지 않습니다. 단, deadline 직전 이미 상관된 A를 Ticket 전달 gate에서 늦게 확인한 경우에는 server waiter가 해소됐으므로 session을 닫지 않고 known token을 보상 release한 뒤 Indeterminate로 끝냅니다. 이미 상관된 T/B는 확정 미획득입니다.
  • 공식 client API는 wire에 없는 min_work_budget을 필수로 받습니다. critical work + 예상 pause + DB commit/rollback 종료의 최소 합이며 0..250초, 정규화된 lease 이하여야 합니다. 위반하면 frame을 보내기 전에 UnsupportedDuration/InsufficientLease 계열 오류를 반환합니다.
  • 키 길이는 글자 수가 아니라 바이트 수입니다 — 한글은 UTF-8에서 글자당 3바이트이므로 최대 42글자입니다.
  • owner는 응답 상관 ID일 뿐 권한이 아닙니다. 값이 겹쳐도 active token을 반환하거나 lease를 갱신하지 않습니다. 다만 한 클라이언트의 동시에 진행 중인 요청끼리는 응답 매칭이 모호하지 않게 서로 다른 1 이상의 값을 사용해야 합니다. 공식 클라이언트는 local counter가 0이 되거나 wrap하면 새 acquire를 fail-closed합니다.
  • bad_key는 빈 키, 128바이트 초과, 스페이스·개행 포함, 유효하지 않은 UTF-8 모두에 해당합니다. 공식 클라이언트는 여기에 더해 \r도 보내지 않습니다 — \r로 끝나는 키는 눈에 안 보이는 채로 다른 키가 되기 때문입니다.
  • 공식 클라이언트의 explicit release와 token을 이미 아는 보상 release는 호출·enqueue 시점부터 절대 5초 안에서만 재접속·재시도합니다. 이 deadline은 lease 길이까지 연장되지 않습니다. R을 확인하면 성공, N이면 이미 사라졌거나 현재 token이 아님으로 구분하고, 응답을 확인하지 못하면 성공으로 추정하지 않습니다. 보상 queue가 가득 차면 안전한 최후 수단인 lease expiry에 맡기며 queue를 무제한으로 키우지 않습니다.

응답 필드 (S→C)

필드타입범위나타나는 응답
tokenu64 BE1 이상, 발급마다 증가A(신규 발급) · R/N(요청 에코)
owneru64 BE요청 값 그대로A · T · B (요청 에코)
keyUTF-8요청 값 그대로 (1~128B)A · T · B · R · N
addrUTF-8host:portM · L
reasonASCII정해진 8가지E

토큰은 0을 발급하지 않습니다. 싱글은 현재 process lifetime의 counter, 클러스터는 합의로 복제된 counter를 사용하며 overflow 직전에는 새 Grant를 fail-closed합니다. wall clock이나 난수로 재시작 단조성을 주장하지 않습니다.

고정 헤더 길이

op 뒤에 오는 고정 길이 이진 구간입니다. 이 바이트들은 0x0A를 포함할 수 있으므로 파서는 개행을 찾기 전에 이 길이만큼 먼저 소비해야 합니다.

방향op고정 헤더구성
C→SA10 Bwait(1) + lease(1) + owner(8)
C→SR8 Btoken(8)
S→CA16 Btoken(8) + owner(8)
S→CT · B8 Bowner(8)
S→CR · N8 Btoken(8)
S→CM · L · E0 B없음 (op 뒤 바로 텍스트)

바이트가 부족하면 E bad_request입니다.

프레임 크기

항목
프레임 상한 (\n 제외)192 바이트 — 초과 시 E line_too_long
최대 A 요청1 + 10 + 128 + 1 = 140 B
최대 R 요청1 + 8 + 128 + 1 = 138 B
최대 A 응답1 + 16 + 128 + 1 = 146 B
빈 프레임 (\n 하나)keep-alive — 서버가 무시

상한 192B는 최대 프레임(146B)보다 넉넉해서, 규격을 지키는 클라이언트는 절대 걸리지 않습니다. 구조적으로 잘못됐거나 oversized인 frame 뒤에는 framing을 더 신뢰하지 않고 연결을 닫습니다.

인증 핸드셰이크

항목
해시SHA-256 (challenge 라인에 명시)
noncebase64url 문자 8자
응답 다이제스트base64url 43자 (패딩 없음)
라인 상한256 바이트
제한 시간10초 (TLS 협상 포함) — 초과 시 연결 종료

자세한 절차는 인증 핸드셰이크를 참고하세요.

서버 측 한계

클라이언트가 직접 지정하지는 않지만 동작에 영향을 주는 값들입니다.

항목기본값설정초과 시
키당 대기자 수2048 (절대 상한 16384)MAX_WAITERSB(사용 중)
전체 대기자 수16384 (절대 상한 65536)MAX_TOTAL_WAITERS해당 acquire에 B
동시 클라이언트 연결1024 (절대 상한 8192)MAX_CONNECTIONS연결 즉시 종료
연결당 밀린 응답256(컴파일 상수)연결 종료 — 응답을 읽지 않는 클라이언트로 판단
전체 in-flight acquire4096(컴파일 상수)해당 acquire에 B
전체 in-flight release512 별도 lane(컴파일 상수)connection 종료 전까지 bounded 대기
cluster active key65536(컴파일 상수)신규 key acquire에 B

읽기 버퍼(4096B), 응답 배치(64개), 시작된 client frame의 progress timeout(5초), single 만료 청소 주기(5초)는 환경변수가 아니라 컴파일 타임 상수입니다. cluster 만료는 전체 scan이 아니라 token을 재검증하는 deadline min-heap으로 처리합니다. 설정 가능한 값의 전체 목록과 유효 범위는 설정 (환경변수)에 있습니다.

전체 acquire·신규 key·전체 waiter admission은 각 hard limit의 90%에서 닫히고 사용량이 75% 미만으로 내려온 뒤 다시 열립니다. 따라서 표의 hard limit에 닿기 전에도 신규 acquire가 B를 받을 수 있으며, release와 Raft 복구용 예약 용량은 이 hysteresis와 분리됩니다.

위반 → 응답 요약

상황응답연결
알 수 없는 opE bad_op닫힘
고정 헤더 부족E bad_request닫힘
lease = 0 또는 251..255E bad_lease닫힘
키가 빔 / 128B 초과 / 스페이스·개행 포함 / UTF-8 아님E bad_key닫힘
프레임 192B 초과E line_too_long닫힘
인증 다이제스트 불일치E auth_failed닫힘
대기열/서버 capacity 포화B + owner + key유지
반납 토큰 불일치N + token + key유지

전체 오류 사유와 연결 처리는 응답 · 오류 E를 참고하세요.