Skip to content

perf(rpc): reuse admitted connections and add a persistent workbench-session mode (2/7) - #545

Merged
wchwawa merged 3 commits into
mainfrom
perf/stack-2-session-transport
Oct 21, 2026
Merged

wchwawa merged 3 commits into
mainfrom
perf/stack-2-session-transport

Conversation

@wchwawa

@wchwawa wchwawa commented Oct 20, 2026

Copy link
Copy Markdown
Member

Related Issue

Relates to #543

Part 2 of 7 of the stack for #543. Stacked on #544 (perf/stack-1-write-pipeline); review only the commits below.

Summary

  • Clients keep a bounded per-endpoint pool of admitted connections shared by transport clones, so an RPC skips the TCP connect and protocol handshake. A pooled connection that fails before any response byte is retried once on a fresh connection.
  • This merges with main's single-write frames and TCP_NODELAY (fix(transport): send each RPC frame in one write and set TCP_NODELAY #533): the request frame comes from length_prefixed_frame, and exchange_frame now reports whether a failure came before or after the first response byte.
  • The owner's accept loop polls the listener instead of sleeping up to 10 ms.
  • nokv workbench-session executes newline-delimited Workbench tool calls over one admitted client and answers each with one JSON line carrying the request id. Each call keeps its own tool boundary; the session is not a transaction.

Commits:

  • 1e1bcdcb9c perf(rpc): reuse admitted connections and wake accept on demand
  • 932dc9321e feat(cli): add a persistent workbench-session mode

Scope

  • This PR changes one logical boundary only.
  • No unrelated refactor, benchmark, metadata model, Holt layout,
    object-store, agent interface, or docs change is mixed in.
  • The linked issue describes the user-visible problem, design decision, or
    maintenance task this PR resolves.
  • Any breaking change is intentional and documented. (none in this PR)
  • No compatibility shim, deprecated alias, or forwarding wrapper was added without a removal condition.

Change Size And Review

  • I checked GitHub's additions plus deletions for this pull request: +581 / -24 (605 lines).
  • If the total is more than 5,000 lines, one core maintainer other than the
    current-head pusher approved the exact current head commit. Not applicable: under 5,000 lines.
  • This change is still small enough for a focused review; approval count is
    not being used to justify mixed package or lifecycle boundaries.

Code Contract (Code Changes Only)

  • Not applicable; this is a docs/config-only change.
  • Package boundaries follow docs/development/code_contract.md.
  • Shared helpers reuse the standard library or existing repository helpers.
    New generic helper modules are domain-neutral and tested.
  • File names and file placement follow the code contract.
  • New types, interfaces, structs, fields, and functions use domain-specific names.
  • New errors are in the owning package's errors.rs and carry stable error kinds when crossing package boundaries (the only new error type, ExchangeError, is private to the transport module and becomes a TransportError before leaving it).
  • New metrics/stats are owned by the package that reports or serves them (none added).
  • Metadata changes document durability, atomicity, revision-reference
    lifetime, snapshot/commit/event retention, GC epochs, and fail-closed
    recovery boundaries. Not applicable: no metadata change.
  • Placement or routing changes preserve persisted RootId -> LogicalShardId
    affinity, one active writer per shard, owner-epoch fencing, and explicit
    shard-local atomicity; no split root or cross-shard transaction is implied. Not applicable: no placement or routing change.
  • Agent-interface changes keep the transport-free facade and schemas in
    nokv-agent, routing and workflows in nokv-client, and the concrete
    backend plus native full CLI wiring in nokv. (the session mode lives in the nokv CLI and reuses the existing Workbench facade and schemas)
  • User-facing integration guidance orders the native full CLI first, the
    direct Python SDK second, and the Rust SDK third, and does not present the
    deprecated nokv mcp sidecar as a supported NoKV surface. (docs/workbench-contract.md documents the session mode as current behaviour)

Claims and Evidence

  • User-facing documentation distinguishes current, experimental, and
    planned capabilities. (docs/workbench-contract.md documents the session mode as current behaviour)
  • Security claims do not treat a Workbench root or Agent scope as tenant
    authentication or authorization (no security claims).
  • Performance claims state the topology, comparison boundary, cache state,
    run count, and raw-evidence location.
  • Benchmark-only behavior does not alter product semantics.

A workbench_stat inside an admitted workbench-session takes about 0.1 ms, against a full process start, route lookup, provider admission, and connection setup per CLI call (fixed_cost.py in the evidence gist reproduces this; the raw output and repetition count of those single-shot timings were not retained). Connection reuse has no separate end-to-end number; the stack-level harness results are in #543.

Topology for every number: one laptop (Apple M3 Pro, 36 GiB, macOS, APFS, F_FULLFSYNC), one NoKV owner, RustFS in Docker, etcd or a local control directory, fresh storage per trial. The method, run counts, and harness are in the evidence gist.

Validation

  • Command and result: on this head with Rust 1.99.1, the toolchain rust.yml pins: cargo clippy --workspace --all-targets -- -D warnings and the feature clippy runs from rust.yml (nokv-meta/nokv-bench with metadata-read-stats, nokv-meta-holt with read-stats, nokv-server and nokv-bench with restore-crash-test-support) are clean.
  • Command and result: workspace and feature tests ran on the stack top 49949ddea8 (perf/stack-7-time-ordered-ids): 1,209 passed, 0 failed, 13 ignored. They were not rerun on this head.
  • Not run (with reason): the live gates (local-WAL successor recovery, Workbench contract, and restore composition) passed on this stack before its rebase onto fix(transport): send each RPC frame in one write and set TCP_NODELAY #533 and were not rerun after it. Linux was not measured.
  • CI note: rust.yml, DCO, and change governance run only for PRs into main, so this PR gets CI once the PR below merges and GitHub retargets it.

Contributor Sign-off

  • Every commit in this PR includes a DCO Signed-off-by trailer.

Clients keep a bounded per-endpoint pool of admitted connections shared
by transport clones, skipping the TCP connect and protocol handshake per
RPC. A pooled connection that fails before any response byte was closed
by the server; the request is resent once on a fresh connection and the
endpoint's other idle connections are dropped. Quiet probing and a 10 s
age bound keep reuse well inside the server's 30 s idle timeout.

The accept loop polls the listener instead of sleeping up to 10 ms.

Signed-off-by: wchwawa <wch19961116@gmail.com>
nokv workbench-session executes newline-delimited Workbench tool calls
over one admitted client, answering each with one flushed JSON line that
carries the request id. Agent harnesses that call many tools no longer
pay a process start, route lookup, provider admission and connection
setup per call. Each call keeps its own tool boundary; the session is not
a transaction and ids only correlate responses.

Signed-off-by: wchwawa <wch19961116@gmail.com>
@wchwawa
wchwawa merged commit 2776f51 into main Oct 21, 2026
8 checks passed
@wchwawa
wchwawa deleted the perf/stack-2-session-transport branch October 21, 2026 05:01
@github-project-automation github-project-automation Bot moved this from In Progress to Done in NoKV Delivery Oct 21, 2026
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.

2 participants