fix(tarantool-core): send IPROTO_WATCH after authentication - #126
Conversation
8925591 to
f42f64a
Compare
IProtoClientWatchersTest uses connect() without auth. Since watchers are now sent after ping() (TNTP-10388 fix), ping must be called to trigger watcher registration.
- testAuthorization: auth response syncId is now 2 since IPROTO_WATCH is no longer allocated before the auth request (TNTP-10388) - testWatcherRecoveryAfterReconnect: call ping() after reconnect to re-trigger watcher registration, adjust sleep timings
| // it does not send watch message if connection is not connected, | ||
| // it sends immediately after successful connect | ||
| // the watch request is sent later, after authorize() or ping() | ||
| watch(SHUTDOWN_EVENT_KEY, this::shutdownEventCallback); |
There was a problem hiding this comment.
Запрос на регистрацию этого watcher требует зарегистрированного пользователя? Если да, то это тоже надо делать после того, как произошел autorize()
There was a problem hiding this comment.
Да, требует. Этот watcher регистрируется тем же механизмом: отправляется при подключении, а если сервер отклоняет его до авторизации — откладывается и перерегистрируется после authorize().
| } | ||
|
|
||
| @Override | ||
| public CompletableFuture<IProtoResponse> authorize( |
There was a problem hiding this comment.
Решение, когда впускать вотчеры должно решаться не здесь, а выше по вызову
There was a problem hiding this comment.
authorize() — часть публичного API клиента, поэтому именно здесь гарантируется перерегистрация отложенных watcher'ов для прямых вызовов connect() → authorize(). Гостевой сценарий (без authorize()) обрабатывается отдельно — watcher'ы регистрируются сразу после подключения.
Fallback to set watchers after authentication if ER_AUTH_REQUIRED happens on connect.
f42f64a to
c379598
Compare
dkasimovskiy
left a comment
There was a problem hiding this comment.
@bitgorbovsky error-driven подход уже реализован — на ER_AUTH_REQUIRED watcher отправляет onAuthRequired коллбек, который сбрасывает failed state. После authorize() -> updateWatchers() все отложенные watcher'и перереgistруются. ping без updateWatchers — оверхед heartbeat закрыт.
Суть
Сейчас при
gracefulShutdown = trueклиент отправляетIPROTO_WATCHдоIPROTO_AUTH. Для Tarantool EE с включенной опциейsecurity.disable_guest: trueсервер отвечаетER_AUTH_REQUIRED, соединение не устанавливается и циклически переподключается каждую секунду.Регрессия версии 1.7.0 (#102): до неё ошибка watcher не влияла на подключение.
Решение
Регистрация watcher'ов построена по принципу error-driven: ошибка
ER_AUTH_REQUIREDобрабатывается не как сбой, а как сигнал «отложить до авторизации».Поток выполнения:
IProtoClientImpl.connect()отправляет watcher'ы сразу после установления соединения, как и раньше.ER_AUTH_REQUIRED(код 258),WatcherStateMachineне вызывает error handler, а передаёт управление коллбеку, который сбрасывает состояние failed watcher'а и убирает его FSM из реестра.IProtoClientImpl.authorize()после успешной аутентификации вызываетupdateWatchers(), повторно регистрируя все отложенные watcher'и — теперь сервер принимает их.Таким образом, при
disable_guest: trueподписки регистрируются только после завершенияauthorize(), а при гостевом доступе (без авторизации) — сразу вconnect().Запросы, доступные до аутентификации
Tarantool допускает до аутентификации только ограниченный набор IPROTO-запросов:
AUTH— собственно аутентификация;PING— используется для guest-подключения и heartbeat;ID— обмен версиями и фичами протокола;VOTE— голосование в репликации.Любой другой запрос (включая
WATCH) приdisable_guest: trueотклоняется сER_AUTH_REQUIRED. Поэтомуbox.shutdownwatcher приgracefulShutdownнельзя зарегистрировать сразу после greeting — его регистрация откладывается до завершенияauthorize().