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

M · Перемещено

Структураrefresh

Указание, что этот узел не лидер и нужно обратиться к лидеру (только для кластера). В теле — текст клиентского адреса лидера (host:port) — это не Raft-порт, а адрес, к которому клиент может подключиться напрямую.

Официальный клиент запоминает адрес как подсказку о лидере только при точном совпадении с уже зарегистрированным адресом allowlist, после чего закрывает эту session. Acquire, у которого мог быть отправлен хотя бы один байт, не сопоставляется произвольно с M и не пересылается: результат — Indeterminate. Последующие независимые и ещё не захваченные writer-ом неотправленные запросы используют новое соединение с лидером. Если лидер ещё не избран и подсказать нечего, вместо этого приходит E no_leader.

Подробности поведения кластера смотрите в Протокол (кластер).

Обозначение байтов: op — символ ASCII, addr — текст в UTF-8 (переменной длины, N в структуре). Завершающий \n — это 0A.

Поток

Клиент
Follower
Leader
A · acquire (key)
M · moved (адрес лидера)
закрыть старую session · отправленный acquire = Indeterminate
следующий независимый acquire начинается у лидера
запросответ

В M нет owner и key, а одна session может смешивать несколько acquires. При переходе leader→follower запросы в процессе commit могут сосуществовать с отклонёнными follower-ом, поэтому один M не доказывает неполучение конкретного pending acquire. Это консервативное правило предотвращает дубли acquire и продление lease тем же owner.