Skip to content

fix: a refused caching opt-in re-tracks the connection and reruns the request - #22

Merged
CMGS merged 7 commits into
masterfrom
fix/caching-window
Sep 10, 2026
Merged

CMGS merged 7 commits into
masterfrom
fix/caching-window

Conversation

@CMGS

@CMGS CMGS commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Three things: the last open row of the loc-justify cut-list, the reply cache's refused-opt-in intermittent, and an ownership walkthrough of the whole crate.

  • Probe::publish is inlined into conduct, which already stores the preference (−3 lines).
  • Dials, rearms and tracker arrivals log at debug level, so a tracking anomaly can be read back from a proxy log.
  • A backend that answers a fill's CLIENT CACHING YES with the tracking-off error is now harmless: the pairing loop reports the refusal, the connection sends its current tracking frame again on its own account (logged at warn once the frame is written), and the request runs again without the opt-in, abandoning its fill, so the client sees its reply and nothing fills. A fan-out part reruns at its slot's current owner; a single request reruns while it is the session's last in flight, since a rerun behind later commands would reorder them. Only a request that held a fill reruns, so an application error of the same text never runs a command twice. Connections resolve the tracking frame from the shared map at handshake instead of carrying one captured at dial time.
  • The ownership walkthrough (every source file read in full for clones, copies and borrow shapes) applied its per-command rows: a remembered script is stored as its SCRIPT LOAD frame, so a watched EVALSHA takes a refcount instead of copying the body; the dispatch subcommand lookup clones the positioned argument iterator instead of re-scanning the frame; a watched command checks its connection through the lease borrow instead of cloning the Rc; the writer's ready buffer gets the capacity valve its siblings have; IOV_STACK grows to 64 so a pipelined batch keeps its iovec on the stack.

The refusal was seen twice in about forty compatibility-matrix runs of the redis 8.2 / reply-cache cell and never in about 120 isolated runs of the same cell; every fill path reads as covered by the dial-time frame or the tracker's rearm, so this closes the effect rather than a window that could be named. Nothing new runs on the reply path outside the existing error branches.

Measured on a 128-master rig, 64 workers, three arms rotated over nine rounds, P16 1000 conns: the fix against master GET 8.65M → 8.72M (+0.9%, A/A +0.05%), SET 9.01M → 9.04M (+0.4%, A/A −0.2%); the final head GET 8.67M → 8.77M (+1.3%, median +0.0%, A/A +0.9%), SET 9.10M → 9.08M (−0.2%, A/A −0.6%). Flat inside the A/A floor both times.

Gates: unit 118; the 15-cell compatibility matrix green; ct1 IT ×8 green, functional suite 165 / 163 passed. Review converged.

Probe::publish had one caller; conduct stores the four atomics itself.
… request

Twice in ~40 matrix runs a backend answered a fill's CLIENT CACHING YES
with the tracking-off error, and the client saw that error; ~120 runs
of the same cell in isolation never reproduce it, and every fill path
reads as covered by the dial-time frame or the rearm. The failure is
now harmless: the pairing loop reports a refused opt-in (logged at
warn with the connection), the connection sends its current tracking
frame again on its own account (a pending entry with no sink), and
the writer reruns the request without the opt-in when nothing later
holds a sequence, abandoning the fill. Connections look the frame up
from the shared map at handshake instead of carrying one captured at
dial time.
…equest

A fan-out part whose opt-in the connection refused reran nowhere: its
error merged into the client's reply. The part now scatters again to its
node without the head, after the fill it held is abandoned by the
error reply.

The single-request rerun keyed on the error text alone, so an
application error of the same text on a plain command would run it
twice; the rerun now requires the in-flight entry to hold a fill. The
no-owner path leaked the detached fill and left the topology stale; it
abandons the fill and asks for a refresh like the other bounces.

The refusal log moves next to the tracking frame write, so it is seen
only when the frame is on the wire, and pair_replies loses the address
it carried for it.
The rerun indexed the fresh topology with the node index the part was
planned with; a refresh between the plan and the refusal can renumber
the nodes, sending the rerun elsewhere. The part's slot is resolved
against the fresh topology instead, as the single-request rerun does.
Four opus readers walked every source file in full for clones, copies
and borrow shapes; the rows on a per-command path that a borrow or a
move serves as well are applied here, the rest are recorded.

- a remembered script is stored as its SCRIPT LOAD frame, built once
  from the request, so a watched EVALSHA takes a refcount instead of a
  copy of the body, and SCRIPT LOAD copies the body once instead of
  twice
- the dispatch subcommand lookup clones the positioned argument
  iterator instead of re-scanning the frame header and the name
- a watched command checks its connection through the lease borrow
  instead of cloning the Rc to read one flag
- the writer's ready buffer gets the excursion valve the parked ring,
  the timings and the fan-out gates already have

IOV_STACK stays at 16: 97743c8 measured 64 slower by 0.2-3.0% on the
default cells, since the array is initialized per writev and default
batches average 1.3 frames.

Also folds pair_replies' comment to one line.
The topology the rerun resolves its owner from can be one slot move
stale, so the rerun could meet MOVED or ASK and merge it into the
client's reply. A rerun's reply now takes the same one redirect a
first-pass part takes; the redirect step is one helper for both.
@CMGS
CMGS merged commit 039682e into master Sep 10, 2026
4 checks passed
@CMGS
CMGS deleted the fix/caching-window branch September 10, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant