docs(arch): unweld CallClient from QUIC — spawn_dispatch primary, connect convenience (ADR-017 Am. 2026-07-13)
Same fix as ADR-080 (ChannelClient) applied to the call crate. The existing code already had the right structure — spawn_dispatch is not feature-gated (transport-agnostic), connect is #[cfg(feature = "quinn")] — but the docs inverted the framing: connect was 'primary,' spawn_dispatch was 'lower-level.' That welding masked the call protocol's transport-agnosticism (ADR-012 EventEnvelope; ADR-065 from_stream/from_bidi accept any AsyncRead + AsyncWrite). Changes: - client-and-adapters.md: reframe spawn_dispatch as the transport- agnostic primary constructor (one-way door), connect as the QUIC convenience (two-way door, feature-gated on quinn). Mirror the from_connection / connect_quic pattern from ADR-080/channel-client.md. Fix all 'QUIC-backed' / 'over QUIC' / 'opens a QUIC connection' framing to be transport-agnostic. Fix from_call description, adapter location map, exchange-of-operations example, Constraints section. - call-protocol.md: 'runs over QUIC bidirectional streams' → 'runs over any ordered, reliable bidirectional stream.' Fix stream model, stream lifecycle (connection drop / stream reset now list all transports, not just QUIC). Fix CallConnection.connection doc comment. - operation-registry.md: FromCall provenance comment 'QUIC forwarding stub' → 'call-protocol forwarding stub.' Fix from_call description. - call README.md: fix client-and-adapters.md description, fix design principle #11 framing. - ADR-017: add Amendment (2026-07-13) documenting the spawn_dispatch / connect reframe, mirroring ADR-080's amendment. - overview.md, architecture README: update ADR-017 and client-and-adapters.md table summaries. - OQ-015, OQ-007: fix 'opens QUIC connections' / 'bidirectional QUIC streams' framing in resolution text. No code changes — spawn_dispatch and connect already exist with the right feature-gate structure. This is a documentation reframe.
This commit is contained in:
1 parent
a26401aadd
commit
b0cc0a01b7
9 files changed
+135
-46
No files matched your search
@@ -2,7 +2,7 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (amended 2026-06-26 — see "Amendments" below)
|
||||
Accepted (amended 2026-06-26 and 2026-07-13 — see "Amendments" below)
|
||||
|
||||
## Context
|
||||
|
||||
@@ -439,4 +439,46 @@ served by consuming `OperationSpec` directly. The §5 "adapters live in
|
||||
alknet-call" one-way-door statement is corrected above to "the adapter
|
||||
trait lives in `alknet-call`; implementations live with their transport."
|
||||
See [ADR-066](066-from-jsonschema-as-http-adapter.md) and
|
||||
[client-and-adapters.md](../crates/call/client-and-adapters.md) §"from_jsonschema".
|
||||
[client-and-adapters.md](../crates/call/client-and-adapters.md) §"from_jsonschema".
|
||||
|
||||
## Amendments (2026-07-13)
|
||||
|
||||
### `CallClient` transport-agnostic API (mirrors ADR-080's amendment)
|
||||
|
||||
The §1 Decision framed `CallClient::connect(addr: SocketAddr,
|
||||
credentials)` as the primary constructor and described it as "opens a
|
||||
QUIC connection." The operational spec
|
||||
([client-and-adapters.md](../crates/call/client-and-adapters.md))
|
||||
framed `spawn_dispatch(connection)` as the "lower-level API" that
|
||||
`connect()` uses after the QUIC dial. That framing welded the
|
||||
client-side one-way-door API to QUIC — the same welding ADR-065
|
||||
unwound on the server side and ADR-080 corrected for `ChannelClient`.
|
||||
|
||||
The call protocol is transport-agnostic (ADR-012 EventEnvelope framing;
|
||||
ADR-065 `Connection::from_stream`/`from_bidi` accept any
|
||||
`AsyncRead + AsyncWrite`). The client side is half of that protocol
|
||||
and must not be coupled to a transport. This amendment reframes the
|
||||
existing code (which already has the right structure —
|
||||
`spawn_dispatch` is not feature-gated, `connect` is
|
||||
`#[cfg(feature = "quinn")]`):
|
||||
|
||||
- **`CallClient::spawn_dispatch(connection: Connection)`** — the
|
||||
transport-agnostic primary constructor and the one-way-door API.
|
||||
Takes a pre-established `Connection` (any transport), spawns the
|
||||
shared dispatch loop, returns a live `CallConnection`. Mirrors the
|
||||
server-side `CallAdapter::handle(Connection)` and
|
||||
`ChannelClient::from_connection` (ADR-080).
|
||||
- **`CallClient::connect(addr, credentials)`** — a QUIC convenience
|
||||
constructor: dial QUIC (feature-gated on `quinn`), then
|
||||
`spawn_dispatch`. Additive and two-way-door. `connect_tcp_tls`,
|
||||
`connect_webtransport`, etc. join it as transports are added,
|
||||
without touching the `spawn_dispatch` contract.
|
||||
|
||||
The door-type classification is unchanged: `spawn_dispatch` is one-way
|
||||
(the handler-facing surface), `connect` is two-way (additive
|
||||
convenience). The `AlknetClient` extraction (OQ-55 — the shared
|
||||
dial+TLS seam) remains deferred; what is deferred is the shared *dial*,
|
||||
not a QUIC-welded client API. `spawn_dispatch` is decided now.
|
||||
|
||||
See [client-and-adapters.md](../crates/call/client-and-adapters.md)
|
||||
§"CallClient" for the reframed operational spec.
|
||||
Reference in new issue
Block a user