Сейчас идёт тестирование: код на GitHub будет открыт после завершения.

Правила сопоставления ответов (реализация клиента)

Поскольку порядок ответов может отличаться от порядка запросов (ответ на захват, вставший в очередь, приходит только когда подходит его очередь), клиент должен сопоставлять ответы запросам по следующим правилам — это правила демультиплексирования, разделяющие вперемешку приходящие по одному соединению ответы по их запросам.

ПравилоСодержание
Ключ сопоставленияПодтверждённый отказ из-за capacity очереди/сервера; сразу Busy, без внутреннего retry
Несколько запросов с одинаковым (op, ключ)нельзя полагаться на FIFO — обязательно определять по идентификатору. См. пояснение ниже
Момент регистрацииожидающий регистрируется до отправки запроса (чтобы избежать гонки, когда ответ приходит раньше)
Обработка N/Tвозвращаются как не-ошибочные значения («отсутствовало»/«таймаут»)
Обработка Bочередь переполнена — не завершать вызов ошибкой сразу, а повторять с backoff в пределах бюджета wait
Обработка MСохранить как leader hint только allowlisted address и закрыть; без owner/key нельзя связать с отправленными pending
Обработка LОбновить только leader hint и оставить соединение; уведомление сервера, не ответ
E no_leader / E not_active / E auth_failedЗакрыть и применить backoff по типу ошибки; no_leader также сбрасывает hint
Прочие E / неизвестные ответыНельзя коррелировать, значит connection-fatal; отправленные acquire становятся Indeterminate
Ответ без ожидающегоНесоответствие protocol/session: закрыть. Для A передать известный exact token в reserved release lane

Почему сопоставлять нужно по идентификатору, а не по FIFO

Даже для одного key немедленный успех, ожидание в queue и отказ B завершаются в разное время. Несколько keys также pipelined в одном соединении. Не сопоставляйте FIFO; вместе проверяйте echoed identifier, op и key.

Прерванные запросы и осиротевшие блокировки

Если отменённый запрос уже получил grant на сервере, lock может остаться. После отправки хотя бы одного byte без окончательного ответа результат — Indeterminate. Не повторяйте A с тем же owner как запрос статуса. Только если token уже распознан, отправьте best-effort exact-token R; неизвестный grant вернётся по lease expiry.

Поэтому после cancel после отправки или framing error соединение закрывается. Удаление лишь pending может оставить ответ без получателя. Socket close не доказывает release committed grant: exact-token R если известен, иначе Indeterminate до lease expiry.