From b014340ea4c4e8d640035faa602fa9e47d2e7f49 Mon Sep 17 00:00:00 2001 From: Tin Dang Date: Sat, 11 Jul 2026 01:31:21 +0700 Subject: [PATCH] =?UTF-8?q?fix(server):=20CLIENT=20TRACKING=20unreachable?= =?UTF-8?q?=20on=20monoio=20=E2=80=94=20admin=20catch-all=20consumed=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the H-3 ACL reorder (#258), CLIENT TRACKING ON|OFF answered "ERR unknown subcommand 'TRACKING'" on the monoio runtime (the production default) at every shard count. try_handle_client_admin runs before try_handle_client_tracking in the frame loop, and its unknown-subcommand fallback consumed TRACKING before the dedicated handler could see it — RESP3 invalidation push was entirely dead. Invisible to CI: the test matrix runs the tokio handler (handler_sharded), whose CLIENT intercept ordering differs, so all 5 client_tracking_invalidation black-box tests kept passing there while failing deterministically against a monoio binary. Fix: try_handle_client_admin falls through (returns false) for TRACKING, letting try_handle_client_tracking own it. Both handlers sit after the ACL gate, so the H-3 deniability guarantee is unchanged. Verification: all 5 client_tracking_invalidation tests re-green against the monoio binary (were 5/5 FAILED at the merge base, control-tested); fmt + clippy clean on default and runtime-tokio,jemalloc feature sets. Refs: regression introduced by #258; tests from #234 author: Tin Dang --- CHANGELOG.md | 14 ++++++++++++++ src/server/conn/handler_monoio/dispatch.rs | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76c7bbd7c..e05f8ea40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed — CLIENT TRACKING dead on the monoio runtime (H-3 reorder regression) + +- Since the H-3 ACL reorder (#258), `CLIENT TRACKING ON|OFF` answered + `ERR unknown subcommand 'TRACKING'` on the monoio runtime (the production + default) at every shard count: `try_handle_client_admin` runs before + `try_handle_client_tracking` in the frame loop and its unknown-subcommand + fallback consumed TRACKING before the dedicated handler could see it. + RESP3 invalidation push was therefore entirely unavailable. Invisible to CI + because the test matrix exercises the tokio handler (`handler_sharded`), + whose intercept ordering differs. +- `try_handle_client_admin` now falls through for TRACKING (both handlers are + post-ACL, so the H-3 deniability guarantee is unchanged). Re-greens all 5 + `client_tracking_invalidation` black-box tests on monoio. + ### Fixed — `txn_kv_wiring` integration test port-collision flake - `start_txn_server` picked a port from a throwaway `bind(:0)` probe, dropped diff --git a/src/server/conn/handler_monoio/dispatch.rs b/src/server/conn/handler_monoio/dispatch.rs index 9f4a5fb0c..d2e3bdd65 100644 --- a/src/server/conn/handler_monoio/dispatch.rs +++ b/src/server/conn/handler_monoio/dispatch.rs @@ -854,6 +854,14 @@ pub(super) fn try_handle_client_admin( } if let Some(sub) = cmd_args.first() { if let Some(sub_bytes) = extract_bytes(sub) { + // TRACKING is owned by `try_handle_client_tracking`, which runs + // AFTER this handler in the frame loop (both are post-ACL). The + // unknown-subcommand fallback below must not swallow it — that + // regression (H-3 reorder, #258) made CLIENT TRACKING answer + // "unknown subcommand" on the entire monoio runtime. + if sub_bytes.eq_ignore_ascii_case(b"TRACKING") { + return false; + } if sub_bytes.eq_ignore_ascii_case(b"LIST") { crate::client_registry::update(client_id, |e| { e.live.touch(