You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cache ClusterClient per (seed, governors); thread governors through _resolve_leader
Two compounding problems in the dbapi leader-discovery probe path
(connection._resolve_leader, called by _build_and_connect):
1. Configuration silently dropped at the first hop. _resolve_leader
constructed ClusterClient(store, timeout=timeout) with no other
governors, so an operator who set trust_server_heartbeat=True saw
the FIRST round-trip — leader discovery — running with the default
opt-out. Likewise max_total_rows / max_continuation_frames were
dropped for admin paths reachable through the resolved client.
2. Single-flight collapse / leader-tracker fast-path dead at this
layer. Each _resolve_leader call constructed a brand-new
ClusterClient and discarded it on return; the _find_leader_tasks
slot map and _last_known_leader cache went with it. Under N
concurrent SA pool checkouts after a leader flip, the cluster
sees N independent leader-discovery sweeps where one would
suffice.
Thread the full governor set through _resolve_leader, and add a
process-wide ClusterClient cache keyed by (address, timeout,
max_total_rows, max_continuation_frames, trust_server_heartbeat).
The cache is wholesale-invalidated on fork via the same _current_pid
token DqliteConnection uses for fork-safety; bounded at 32 entries
(LRU-ish drop) so adversarial governor-fragmentation cannot leak
unbounded.
The existing cluster-level fixes (ISSUE-1402 single-flight, ISSUE-1403
last-known-leader) presupposed ClusterClient reuse; without this fix
those benefits were largely defeated at the dbapi layer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments