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

A · Захват

Структураrefresh

Запрос на захват блокировки. lease — страховка, позволяющая серверу вернуть key после истечения срока, если клиент исчез без release. wait ограничивает ожидание в секундах; 0 означает единственную немедленную попытку без очереди. Бесконечного ожидания нет. Успех — Получено A, истечение ожидания — Timeout T, заполнение очереди/ёмкости сервера — Занято B.

owner — Идентификатор корреляции ответа

ownerидентификатор ответа одной попытки acquire. Клиент создаёт новый для каждого вызова, а сервер echo его в A, T и B, чтобы сопоставлять ответы в pipeline.

owner не является полномочием на lock или fencing token. Повтор тех же key и owner не возвращает active token и не продлевает lease. Если мог быть отправлен хотя бы один байт, но ответ не подтверждён, клиент не должен автоматически повторять acquire с тем же owner: результат — Indeterminate. Входить в critical section нельзя; ненаблюдаемый grant будет возвращён не позднее lease expiry.

Официальные клиенты один раз создают monotonic deadline всей операции из нормализованного wait caller и сохраняют этот deadline и owner при повторах, которые гарантированно не были отправлены. Непосредственно перед отправкой writer округляет оставшееся время вверх и заново вычисляет wire wait, поэтому позднее подключение не начинает на server новые 255 секунд ожидания. Queued-запрос после общего deadline не отправляется; если он уже мог быть отправлен, закрывается его точная session и результатом становится Indeterminate. Если уже сопоставленный перед deadline A обнаружен поздно на gate выдачи Ticket, закрывать session не нужно, но планируется компенсирующий release exact token и возвращается Indeterminate. Сопоставленные T и B остаются соответственно окончательными timeout и busy.

Исходный wait=0 остаётся немедленной попыткой на wire. В течение отдельного пятисекундного transport deadline клиент может выбрать другое подключение и повторить запрос с тем же owner только пока запрос гарантированно не отправлен; фактическая server-side попытка по-прежнему ровно одна. После возможной отправки повтор запрещён.

Обозначение байтов: op — символ ASCII, wait/lease — бинарные (u8, big-endian), owner — бинарный (u64, big-endian), key — текст в UTF-8 (переменной длины, N в структуре). Завершающий \n — это 0A. Фиксированный заголовок — бинарное значение и может содержать 0x0A, поэтому его нужно сначала вычитать по количеству байт, и лишь затем искать перевод строки.

Поток

Клиент
Сервер
A · acquire (key · wait · lease · owner)
ключ свободен → выдан немедленно
A · acquired (token)
занят → ожидание очереди в FIFO
при наступлении очереди A · acquired (token)
wait превышен → T · timeout
wait=0 + занят → T · немедленно не получен
очередь переполнена → B · busy
запросответ

Полные правила поведения по состояниям ключа смотрите в Матрице запрос × состояние ключа.