Saat ini dalam pengujian: kode GitHub akan dibuka setelah selesai.

Batasan Field dan Rentang Nilai

Field request (C→S)

FieldTipeRentang validArtiSaat dilanggar
opASCII 1BA(0x41) · R(0x52)Jenis requestE bad_op
waitu80255 (detik)0 mencoba langsung tanpa antrean; 1..255 membatasi waktu tunggu acquire— (selalu valid karena tipe)
leaseu81250 (detik)Lease; 0 dan 251..255 ditolak/reservedE bad_lease
owneru64 BE02^64-1 seluruhnyaPenanda percobaan acquire (dibuat klien)— (server tidak memeriksanya)
tokenu64 BEnilai yang diterbitkan serverMenentukan apa yang dirilis (khusus R)N jika tidak cocok
keyUTF-81 – 128 byteNama lock. Tidak boleh spasi (0x20) atau newline (0x0A)E bad_key
  • Tidak ada wait/lease tanpa batas. Klien resmi membulatkan pecahan detik ke atas, memvalidasi rentang, dan mengembalikan error input eksplisit sebelum mengirim tanpa clamp. Lease default adalah 30 detik.
  • Dalam API client resmi, wait adalah batas keseluruhan acquire sejak pemanggilan dimulai, mencakup local queue, retry koneksi yang pasti belum terkirim, write, dan respons. Satu monotonic operation deadline dibuat sekali saja; tepat sebelum benar-benar mengirim, writer memasukkan pembulatan ke atas u8 dari detik tersisa ke wait pada frame. Karena itu, koneksi yang terlambat atau failover yang pasti belum terkirim tidak dapat memulai ulang server wait. Saat deadline, request yang masih di queue berakhir timeout dan pasti belum terkirim; jika satu byte saja mungkin telah terkirim, session yang tepat itu ditutup dan hasilnya Indeterminate. Hanya wait=0 asli yang memakai wire 0, dan percobaan langsung ini memiliki I/O deadline terbatas tersendiri agar transport yang macet tidak ditunggu selamanya. Jika A yang telah berkorelasi tepat sebelum deadline baru ditemukan di gate penyerahan Ticket, server waiter sudah selesai: session tetap terbuka, exact token yang diketahui dilepas sebagai kompensasi, dan hasilnya Indeterminate. T/B yang berkorelasi tetap merupakan kegagalan memperoleh lock yang definitif.
  • Untuk wait=0 asli, perilaku wire dan server tetap satu percobaan langsung tanpa queue. Dalam transport deadline lima detik yang terpisah, kegagalan yang pasti belum terkirim boleh memilih koneksi lain dan retry dengan owner yang sama. Setelah satu byte saja mungkin telah terkirim, acquire tidak pernah dikirim ulang.
  • API klien resmi mewajibkan min_work_budget yang tidak ada di wire. Nilai ini mencakup critical work + perkiraan pause + penyelesaian DB commit/rollback, berada di 0..250 detik, dan tidak melebihi lease ternormalisasi. Pelanggaran gagal sebelum kirim dengan error kelas UnsupportedDuration/InsufficientLease.
  • Panjang key dihitung dalam byte, bukan karakter — aksara Korea memakai 3 byte per karakter di UTF-8, jadi maksimal 42 karakter.
  • owner hanya ID korelasi respons, bukan otoritas. Memakai ulang nilainya tidak mengembalikan active token atau memperbarui lease. Request in-flight bersamaan dari satu klien harus memakai nilai nonzero berbeda; saat counter menjadi 0 atau wrap, klien resmi fail-closed.
  • Release eksplisit dan kompensasi untuk token yang sudah diketahui memiliki 5 detik absolut sejak call/enqueue, termasuk reconnect dan retry. R memastikan sukses; N berarti sudah hilang atau bukan token saat ini. Tanpa respons tidak pernah dianggap sukses; antrean kompensasi terbatas yang penuh bergantung pada lease expiry.
  • bad_key mencakup key kosong, lebih dari 128 byte, mengandung spasi atau newline, dan UTF-8 yang tidak valid, semuanya sama. Klien resmi juga tidak pernah mengirim \r — key yang diakhiri \r akan diam-diam menjadi key yang berbeda.

Field respons (S→C)

FieldTipeRentangMuncul pada
tokenu64 BE1 atau lebih, naik setiap penerbitanA (penerbitan baru) · R/N (echo request)
owneru64 BEpersis nilai requestA · T · B (echo request)
keyUTF-8persis nilai request (1–128 B)A · T · B · R · N
addrUTF-8host:portM · L
reasonASCII8 nilai yang ditetapkanE

Server tidak pernah menerbitkan token 0. Single memakai counter selama process lifetime saat ini; cluster memakai counter yang direplikasi konsensus dan fail-closed sebelum overflow. Wall clock atau acak tidak menjamin monotonisitas setelah restart.

Panjang header tetap

Bagian biner berpanjang tetap yang mengikuti op. Byte-byte ini bisa mengandung 0x0A, jadi parser harus mengonsumsi panjang ini sebelum mencari newline.

ArahopHeader tetapSusunan
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 Btidak ada (teks langsung setelah op)

Jika byte-nya kurang, hasilnya E bad_request.

Ukuran frame

ItemNilai
Batas frame (tanpa \n)192 byte — jika lebih: E line_too_long
Request A maksimum1 + 10 + 128 + 1 = 140 B
Request R maksimum1 + 8 + 128 + 1 = 138 B
Respons A maksimum1 + 16 + 128 + 1 = 146 B
Frame kosong (hanya \n)keep-alive — diabaikan server

Batas 192B di atas frame terbesar (146B), sehingga klien patuh tidak akan mencapainya. Setelah frame cacat struktur atau oversized, framing tidak lagi dipercaya dan koneksi ditutup.

Auth handshake

ItemNilai
HashSHA-256 (dicantumkan di baris challenge)
nonce8 karakter base64url
Digest respons43 karakter base64url (tanpa padding)
Batas baris256 byte
Batas waktu10 detik (termasuk negosiasi TLS) — lewat dari itu koneksi ditutup

Prosedur lengkapnya ada di Auth handshake.

Batas sisi server

Nilai ini tidak disetel langsung oleh klien, tetapi memengaruhi perilakunya.

ItemDefaultSetelanSaat terlampaui
Waiter per key2048 (batas 16384)MAX_WAITERSB (busy)
Total waiter16384 (batas 65536)MAX_TOTAL_WAITERSB untuk acquire
Koneksi client bersamaan1024 (batas 8192)MAX_CONNECTIONSKoneksi langsung ditutup
Reply tertunda per koneksi256compile-timeKoneksi lambat ditutup
Acquire in-flight global4096compile-timeB untuk acquire
Release in-flight global512, lane terpisahcompile-timeMenunggu terbatas sampai koneksi tutup
Key aktif cluster65536compile-timeB untuk key baru

Read buffer (4096B), batch respons (64), progress timeout frame client yang dimulai (5 detik), dan single expiry sweep (5 detik) adalah konstanta compile-time. Cluster expiry memakai deadline min-heap yang memvalidasi token, bukan scan penuh. Lihat Konfigurasi.

Admission semua acquire, key baru, dan semua waiter ditutup pada 90% hard limit dan baru dibuka setelah turun di bawah 75%. Karena itu acquire baru dapat menerima B sebelum batas; capacity cadangan untuk release dan pemulihan Raft terpisah dari hysteresis ini.

Ringkasan pelanggaran → respons

SituasiResponsKoneksi
op tidak dikenalE bad_opditutup
Header tetap kurangE bad_requestditutup
lease = 0 atau 251..255E bad_leaseditutup
Key kosong / lebih dari 128 B / mengandung spasi atau newline / bukan UTF-8E bad_keyditutup
Frame lebih dari 192 BE line_too_longditutup
Digest auth tidak cocokE auth_failedditutup
Antrean penuhB + owner + keytetap
Token rilis tidak cocokN + token + keytetap

Daftar lengkap alasan error dan penanganan koneksinya ada di Response · Error E.