Atualmente em testes: o código do GitHub será aberto quando concluído.

Restrições de Campo e Faixas de Valores

Campos de Requisição (C→S)

CampoTipoFaixa válidaSignificadoEm caso de violação
opASCII 1BA(0x41) · R(0x52)Tipo de requisiçãoE bad_op
waitu80255 (segundos)0 tenta imediatamente sem fila; 1..255 limita a espera de aquisição— (sempre válido pelo tipo)
leaseu81250 (segundos)Lease; 0 e 251..255 são rejeitados/reservadosE bad_lease
owneru64 BEtoda a faixa 02^64-1Identificador da tentativa de aquisição (gerado pelo cliente)— (o servidor não valida)
tokenu64 BEvalor emitido pelo servidorIndica o que liberar (só R)N se não conferir
keyUTF-81 – 128 bytesNome do lock. Não pode conter espaço (0x20) nem nova linha (0x0A)E bad_key
  • Não há wait nem lease infinitos. Os clientes oficiais arredondam frações de segundo para cima, validam o intervalo e retornam erro explícito antes de enviar, sem clamp. O lease padrão é 30 segundos.
  • Na API oficial, wait é o limite total do acquire desde o início da chamada, passando por local queue, novas tentativas de conexão definitivamente não enviadas e write, até a resposta. Uma única monotonic operation deadline é criada; imediatamente antes do envio real, o writer grava no wait do frame o teto u8 dos segundos restantes. Assim, uma conexão tardia ou failover definitivamente não enviado não reinicia o server wait. Se a solicitação ainda estiver na queue na deadline, ela termina como timeout definitivamente não enviado; se até um byte puder ter sido enviado, fecha-se essa session exata e o resultado é Indeterminate. Somente um wait=0 original usa wire 0, e essa tentativa imediata tem uma I/O deadline finita separada para não aguardar indefinidamente um transport travado. Se um A já correlacionado pouco antes da deadline só for descoberto no gate de entrega do Ticket, o server waiter já foi resolvido: a session permanece aberta, o exact token conhecido recebe release compensatório e o resultado é Indeterminate. T/B correlacionados continuam sendo não aquisições definitivas.
  • Para um wait=0 original, o comportamento wire e server continua sendo uma única tentativa imediata sem queue. Dentro de sua transport deadline separada de cinco segundos, uma falha definitivamente não enviada pode escolher outra conexão e tentar novamente com o mesmo owner. Depois que até um byte puder ter sido enviado, o acquire nunca é retransmitido.
  • A API oficial exige min_work_budget, ausente do wire. Ele cobre trabalho crítico + pausa esperada + conclusão de commit/rollback DB, fica em 0..250 segundos e não excede o lease normalizado. Caso contrário, falha antes do envio com erro da classe UnsupportedDuration/InsufficientLease.
  • O comprimento da chave é medido em bytes, não em caracteres — caracteres acentuados ocupam 2 bytes em UTF-8, então uma chave só de acentuados chega a 64 caracteres.
  • owner é apenas ID de correlação da resposta, não autoridade. Reutilizá-lo não retorna active token nem renova lease. Requisições in-flight simultâneas do mesmo cliente usam valores não zero distintos; se o contador atingir 0 ou fizer wrap, clientes oficiais falham de modo fechado.
  • Releases explícitos e compensatórios de token conhecido têm 5 segundos absolutos desde call/enqueue, incluindo reconexões e tentativas. R confirma sucesso; N significa já ausente ou token não atual. Sem resposta nunca presume sucesso; uma fila compensatória limitada cheia recorre à expiração do lease.
  • bad_key cobre uma chave vazia, uma que excede 128 bytes, uma que contém espaço ou nova linha, e UTF-8 inválido, todos igualmente. Os clientes oficiais também nunca enviam \r — uma chave terminada em \r se tornaria silenciosamente uma chave diferente.

Campos de Resposta (S→C)

CampoTipoFaixaAparece em
tokenu64 BE1 ou mais, crescendo a cada concessãoA (nova emissão) · R/N (eco da requisição)
owneru64 BEo valor da requisição sem alteraçãoA · T · B (eco da requisição)
keyUTF-8o valor da requisição sem alteração (1–128B)A · T · B · R · N
addrUTF-8host:portM · L
reasonASCIIum dos oitoE

O servidor nunca emite token 0. Single usa contador durante a vida do processo; cluster usa contador replicado por consenso e falha fechado antes de overflow. Wall clock ou aleatoriedade não garantem monotonicidade após reinício.

Tamanhos de Cabeçalho Fixo

O trecho binário de tamanho fixo que vem logo após o op. Esses bytes podem conter 0x0A, então o parser precisa consumir exatamente essa quantidade antes de procurar a nova linha.

DireçãoopCabeçalho fixoComposição
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 Bnenhum (o texto começa logo após o op)

Bytes insuficientes resultam em E bad_request.

Tamanho do Quadro

ItemValor
Limite do quadro (sem o \n)192 bytes — acima disso: E line_too_long
Maior requisição A1 + 10 + 128 + 1 = 140 B
Maior requisição R1 + 8 + 128 + 1 = 138 B
Maior resposta A1 + 16 + 128 + 1 = 146 B
Quadro vazio (apenas \n)keep-alive — ignorado pelo servidor

O limite de 192B supera o maior quadro (146B), então um cliente conforme não o atinge. Após quadro estruturalmente inválido ou oversized, o framing deixa de ser confiável e a conexão é fechada.

Handshake de Autenticação

ItemValor
HashSHA-256 (indicado na linha de challenge)
nonce8 caracteres base64url
Digest de resposta43 caracteres base64url (sem padding)
Limite da linha256 bytes
Tempo limite10 segundos (incluindo a negociação TLS) — a conexão é fechada se exceder

Veja Handshake de Autenticação para o procedimento completo.

Limites do servidor

O cliente não define diretamente estes valores, mas eles afetam seu comportamento.

ItemPadrãoConfiguraçãoAo exceder
Waiters por key2048 (limite 16384)MAX_WAITERSB (busy)
Waiters totais16384 (limite 65536)MAX_TOTAL_WAITERSB para o acquire
Conexões client simultâneas1024 (limite 8192)MAX_CONNECTIONSConexão fechada imediatamente
Replies pendentes por conexão256constante de compilaçãoConexão lenta fechada
Acquires in-flight globais4096constante de compilaçãoB para o acquire
Releases in-flight globais512, lane separadaconstante de compilaçãoEspera limitada até fechar
Keys ativas no cluster65536constante de compilaçãoB para nova key

Read buffer (4096B), batch de respostas (64), progress timeout de quadro client iniciado (5 s) e sweep de expiração single (5 s) são constantes de compilação. Cluster expiry usa deadline min-heap com validação de token, não scan completo. Veja Configuração.

A admissão de acquires, keys novas e waiters globais fecha em 90% do hard limit e só reabre abaixo de 75%. Assim, um acquire novo pode receber B antes do limite; a capacidade reservada para release e recuperação Raft é separada dessa histerese.

Resumo: Violação → Resposta

SituaçãoRespostaConexão
op desconhecidoE bad_opfechada
Cabeçalho fixo incompletoE bad_requestfechada
lease = 0 ou 251..255E bad_leasefechada
Chave vazia / acima de 128B / com espaço ou nova linha / não UTF-8E bad_keyfechada
Quadro acima de 192BE line_too_longfechada
Digest de autenticação divergenteE auth_failedfechada
Fila de espera saturadaB + owner + keymantida
Token de liberação divergenteN + token + keymantida

Para todos os motivos de erro e o tratamento da conexão, veja Resposta · Erro E.