docs(arch): control format is ALPN-specific (not JSON-binding); hub/worker are consumers not sub-crates
Two refinements from the review: 1. Control stream_types (3/4/5) carry ALPN-specific payloads, not JSON. The channels layer is blind to what control stream_types carry — it reassembles bytes and delivers them to the handler. TTY happens to use JSON for its control channel because its control messages map cleanly to JSON; another ALPN might use a binary format. The channels layer does not mandate JSON on control stream_types, the same way it doesn't mandate a format for data stream_types. This prevents the TTY/PTY JSON constraint from becoming a binding constraint on all future channel types. (ADR-071, channels-wire.md) 2. Hub and worker are consumers of channels, not sub-crates. The existing alknet-hub crate IS the channels hub — it depends on channels-call and uses channels as its substrate, with the relay logic (ADR-079) living in alknet-hub. A worker is any crate that uses ChannelClient to dial. There are no channels-hub or channels-worker sub-crates. The dependency direction is: alknet-hub → channels-call → channels-core → alknet-core; worker → channels-call → channels-core → alknet-core. The channels crate has no dependency on alknet-hub or any worker crate. (ADR-081, overview.md)
This commit is contained in:
1 parent
fd83fc1685
commit
3006e29afc
5 files changed
+107
-76
No files matched your search
@@ -40,7 +40,7 @@ protocol work itself.
|
||||
| [078](../../decisions/078-two-pump-shutdown-on-completion.md) | Two-Pump Shutdown-on-Completion Pattern | The two-pump deadlock contract; handler-level, not channels-layer |
|
||||
| [079](../../decisions/079-hub-relay-translate-not-forward.md) | Hub Relay — Translate, Not Transparently Forward | The hub translates channel 0, byte-forwards data channels with ID rewrite |
|
||||
| [080](../../decisions/080-channelclient.md) | ChannelClient — the Client Side of a Channels Connection | `ChannelClient`, QUIC-only; `AlknetClient` deferred (OQ-55) |
|
||||
| [081](../../decisions/081-channels-subcrate-decomposition.md) | channels Sub-Crate Decomposition | `channels-core` (pure multiplexer) / `channels-call` (call coupling) / hub / worker |
|
||||
| [081](../../decisions/081-channels-subcrate-decomposition.md) | channels Sub-Crate Decomposition | `channels-core` (pure multiplexer) / `channels-call` (call coupling + ChannelClient); hub and worker are consumers, not sub-crates |
|
||||
| [070](../../decisions/070-bidistreamsource-trait.md) | BidiStreamSource Trait | The `Connection` extension point `ChannelBidiStreamSource` implements |
|
||||
| [065](../../decisions/065-connection-from-stream-generic-single-stream.md) | `Connection::from_stream` | The transport-agnostic `Connection` the channels layer rides on |
|
||||
| [052](../../decisions/052-alknet-tty-wire-format-and-two-carriage.md) | alknet-tty Wire Format | The 5-byte format the 9-byte format generalizes (amended by ADR-077 — scoped to direct TTY) |
|
||||
|
||||
@@ -48,8 +48,8 @@ stream_types are grouped in threes:
|
||||
| Data | 0 | write (client→server) | data in (stdin equivalent) |
|
||||
| | 1 | read (server→client) | data out (stdout equivalent) |
|
||||
| | 2 | read (server→client) | data err (stderr equivalent, optional) |
|
||||
| Control | 3 | write (client→server) | control in (resize, signal, eof) |
|
||||
| | 4 | read (server→client) | control out (exit, keepalive response) |
|
||||
| Control | 3 | write (client→server) | control in (ALPN-specific format) |
|
||||
| | 4 | read (server→client) | control out (ALPN-specific format) |
|
||||
| | 5 | read (server→client) | control err (optional) |
|
||||
| Future | 6/7/8 | write/read/read | next group, same pattern |
|
||||
| | ... | | |
|
||||
@@ -65,6 +65,13 @@ own flow control, its own EOF. Control is bidirectional via two halves
|
||||
(3 in, 4 out), not one shared stream both sides write to. This resolves the
|
||||
TTY control channel's "not actually bidirectional" flaw (ADR-077).
|
||||
|
||||
**Control payload format is ALPN-specific.** The channels layer is blind to
|
||||
what stream_types 3/4/5 carry — it reassembles bytes and delivers them to
|
||||
the handler. TTY happens to use JSON for its control channel; another ALPN
|
||||
might use a binary format. The channels layer does not mandate JSON on
|
||||
control stream_types, the same way it doesn't mandate a format for data
|
||||
stream_types.
|
||||
|
||||
Not all channels use all sub-streams. The active set is declared at
|
||||
`channel/open` time (ADR-073 `stream_types` field) and fixed for the
|
||||
channel's lifetime.
|
||||
|
||||
@@ -105,18 +105,17 @@ alknet-channels-core
|
||||
|
||||
alknet-channels-call
|
||||
├── alknet-channels-core (ChannelManager, ChannelsAdapter,
|
||||
│ ChannelBidiStreamSource)
|
||||
│ ChannelBidiStreamSource, ChannelClient)
|
||||
├── alknet-call (OperationRegistry, HandlerKind, make_handler,
|
||||
│ make_streaming_handler, CallError, ResponseEnvelope)
|
||||
└── tokio
|
||||
|
||||
alknet-channels-hub (or the hub role within alknet-hub)
|
||||
alknet-hub (the existing hub crate — consumes channels)
|
||||
├── alknet-channels-call
|
||||
└── alknet-call (from_call, CallAdapter, forwarded_for — ADR-079)
|
||||
|
||||
alknet-channels-worker (or the worker/client role)
|
||||
├── alknet-channels-call
|
||||
└── alknet-call (CallClient-equivalent)
|
||||
worker crates (any crate that dials a hub — consumes channels)
|
||||
└── alknet-channels-call (ChannelClient — ADR-080)
|
||||
```
|
||||
|
||||
`alknet-channels-core` is the pure multiplexer — wire format, demux/mux,
|
||||
@@ -125,15 +124,17 @@ only. No `alknet-call` dependency. ALPN-blind, call-protocol-blind,
|
||||
transport-blind. This is where the "streams are streams" insight lives.
|
||||
|
||||
`alknet-channels-call` is the call-protocol coupling — channel 0
|
||||
pre-negotiation as `alknet/call` (ADR-072) and the four lifecycle operations
|
||||
(ADR-073) registered on the call protocol's `OperationRegistry`. This is
|
||||
where the call-protocol coupling lives, isolated from the pure multiplexer.
|
||||
pre-negotiation as `alknet/call` (ADR-072), the four lifecycle operations
|
||||
(ADR-073) registered on the call protocol's `OperationRegistry`, and
|
||||
`ChannelClient` (ADR-080). This is where the call-protocol coupling lives,
|
||||
isolated from the pure multiplexer.
|
||||
|
||||
`alknet-channels-hub` and `alknet-channels-worker` (or the hub/worker roles
|
||||
within `channels-call`) are the two roles: the relay (ADR-079) and the
|
||||
`ChannelClient` (ADR-080). Whether these are separate sub-crates or
|
||||
feature-gated modules within `channels-call` is a two-way-door packaging
|
||||
decision (ADR-081).
|
||||
The hub and worker are **consumers**, not sub-crates. The existing
|
||||
`alknet-hub` crate IS the channels hub — it depends on `channels-call` and
|
||||
uses channels as its substrate, with the relay logic (ADR-079) living in
|
||||
`alknet-hub` alongside its existing peer lifecycle and service discovery
|
||||
responsibilities. A worker is any crate that uses `ChannelClient` to dial.
|
||||
There are no `channels-hub` or `channels-worker` sub-crates.
|
||||
|
||||
See ADR-081 for the full decomposition rationale.
|
||||
|
||||
@@ -249,7 +250,7 @@ All design decisions are documented as ADRs in [decisions/](../../decisions/).
|
||||
| [078](../../decisions/078-two-pump-shutdown-on-completion.md) | Two-Pump Pattern | Shutdown-on-completion contract; handler-level |
|
||||
| [079](../../decisions/079-hub-relay-translate-not-forward.md) | Hub Relay | Translate channel 0, byte-forward data channels with ID rewrite |
|
||||
| [080](../../decisions/080-channelclient.md) | ChannelClient | Client side; QUIC-only; `AlknetClient` deferred (OQ-55) |
|
||||
| [081](../../decisions/081-channels-subcrate-decomposition.md) | Sub-Crate Decomposition | `channels-core` (pure multiplexer) / `channels-call` (call coupling) / hub / worker |
|
||||
| [081](../../decisions/081-channels-subcrate-decomposition.md) | Sub-Crate Decomposition | `channels-core` (pure multiplexer) / `channels-call` (call coupling + ChannelClient); hub and worker are consumers |
|
||||
|
||||
## Open Questions
|
||||
|
||||
|
||||
Reference in new issue
Block a user