Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
911f186629 | ||
|
|
a63f4ed2c9 | ||
|
|
e854947c86 | ||
|
|
660ccf3e76 | ||
|
|
8832160db1 | ||
|
|
dbaaa4ec8c | ||
|
|
126fdec243 | ||
|
|
a9429dfb1d |
+100
@@ -6,6 +6,106 @@ this crate adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.5.0] — 2026-09-18
|
||||
|
||||
### Changed
|
||||
|
||||
- **`alkcall` dependency bumped to 0.8.0** (review 008's remediation
|
||||
wave: the graduation upstream asks + the in-tree channel relay). No
|
||||
code change in this crate — alkcall 0.8.0 is additive on the
|
||||
call-plane JSON and the registry seams, and none of its new surfaces
|
||||
are constructed here: this crate builds no `Establishment` reply
|
||||
fields (the WS ferry passes `Option<OpenEstablisher>` through
|
||||
unchanged; reply-field projection is an establisher-supplier
|
||||
feature), imports no marked specs through `from_call` (the
|
||||
`from_wss` operation filter excludes the protocol-session ops; any
|
||||
domain op the remote serves imports as a forwarding bundle exactly
|
||||
as before), and consumes neither `ChannelRelay` nor
|
||||
`HubLegImports`/`HubLegTemplate` (hub-leg assembly remains the
|
||||
consumer's concern at the assembly layer). One ride-through visible
|
||||
on this crate's discovery surface: for a deployment's
|
||||
`with_ws_openable_alpns` open-op specs whose names are not standard
|
||||
`channels/<seg>/(sub|pub)` shapes, the served `services/list` /
|
||||
`services/schema` output now carries an explicit
|
||||
`channel_open_alpn` string alongside the boolean marker (alkcall
|
||||
0.8.0's U-1, ADR-047 amendment 3) — so hubs relaying through a
|
||||
`from_call` import of those ops reconstruct the marker instead of
|
||||
seeing plain forwarding stubs. Standard-shape open-op names stay
|
||||
byte-stable. Minor bump per the dep-wave convention (0.3.0 rode
|
||||
alkcall 0.6.0; 0.4.0 rode 0.7.0).
|
||||
|
||||
## [0.4.1] — 2026-09-10
|
||||
|
||||
### Changed
|
||||
|
||||
- **`rust-version` floor raised 1.85 → 1.88** (patch bump, no API change).
|
||||
The 1.85 claim was already false at the dependency level: the resolved
|
||||
lockfile pulls `icu_*` 2.x (MSRV 1.86 via `jsonschema` → `idna`) and —
|
||||
since alkcall 0.7.1 — alkcall itself declares 1.88, so 1.85 toolchains
|
||||
cannot build the tree regardless of what Cargo.toml declared. Raising
|
||||
the floor to 1.88 aligns with the ecosystem MSRV decision (noq QUIC
|
||||
path; recorded for alktls in OQ-TLS-08) and breaks no downstream that
|
||||
could build the crate before. Verified: 1.88 toolchain `cargo test
|
||||
--locked` + clippy `--all-targets -D warnings` clean; one 1.88 clippy
|
||||
lint fixed (`uninlined_format_args` in a `forward.rs` test).
|
||||
|
||||
- **`alkcall` dependency consumed at 0.7.1** (lockfile bump; the
|
||||
`version = "0.7"` requirement already covered it). No code change
|
||||
forced — alkcall 0.7.1's changes are its own MSRV-floor raise plus the
|
||||
cf-006/cf-007 feature work already consumed in the 0.7.0 wave.
|
||||
|
||||
## [0.4.0] — 2026-09-07
|
||||
|
||||
### Changed
|
||||
|
||||
- **`alkcall` dependency bumped to 0.7.0** (CF-005/006/007 — the
|
||||
connect-side caller-identity seam + the downstream-findings sweep).
|
||||
No code change in this crate: it constructs no `ServingConfig`
|
||||
(the one struct-literal break — `from_wss` keeps the pure-consumer
|
||||
`ChannelClient::from_connection`; opt-in serving remains the
|
||||
review-006 Part C deferred decision) and the per-call opener-identity
|
||||
overlay (CF-006) is behavior-only upstream — hub-forwarded opens on
|
||||
the WS ferry now resolve the end client's identity instead of the
|
||||
hub's, the intended effect. alkcall 0.7.0's ADR-016 amendment (the
|
||||
protocol-code list is eight codes) resolves the upstream half of
|
||||
review-006 Part C's doc-drift note.
|
||||
|
||||
### Changed (wire-surface behavior)
|
||||
|
||||
- **Gateway error table maps `CONNECTION_CLOSED` → 503 Service
|
||||
Unavailable** (the alkcall 0.7.0 CF-007 amendment makes it the eighth
|
||||
protocol code; ADR-023 amended). Previously it fell to the catch-all
|
||||
500, which misreported a retryable, provably-undelivered call as a
|
||||
permanent server failure. Reachable through the gateway when an
|
||||
imported op's forwarding handler calls into a dropped transport
|
||||
(`from_wss`'s pending-call fail-all is retryable
|
||||
`CONNECTION_CLOSED`). The code is `retryable: true`, so the existing
|
||||
`retry_after` details path applies on 503. Tests pin the mapping and
|
||||
the `Retry-After` passthrough. Behavioral break for HTTP callers
|
||||
matching on the 500 previously emitted for this code — hence a minor
|
||||
bump, not a patch.
|
||||
|
||||
## [0.3.0] — 2026-09-07
|
||||
|
||||
### Changed
|
||||
|
||||
- **`alkcall` dependency bumped to 0.6.0** (review 007's
|
||||
establishment follow-ups sweep). One consumer-visible change: the
|
||||
`OpenHandler` signature gained a plan parameter —
|
||||
`Fn(Value, Option<ChannelPlan>, Connection, AuthContext) ->
|
||||
JoinHandle<()>` — so `OpenableAlpn::new` callers' handler closures
|
||||
gain a `_plan` argument (mechanical). With an establisher attached
|
||||
(ADR-049), its `Establishment.plan` (a typed-opaque
|
||||
`Arc<dyn Any + Send + Sync>`) is threaded process-locally to the
|
||||
handler's plan parameter: ALPN crates dial/allocate in the
|
||||
establisher and deliver the live handle without a side-channel
|
||||
handoff. This crate's WS ferry passes the `Option<OpenEstablisher>`
|
||||
through unchanged and constructs no `Establishment` itself, so the
|
||||
ride is otherwise additive — alkcall 0.6.0's `channels::pump_bidi`
|
||||
helper (ADR-050) is available to data-plane handlers this crate
|
||||
ferries. Docs updated (websocket.md, `OpenableAlpn` field docs,
|
||||
adapter.rs).
|
||||
|
||||
## [0.2.0] — 2026-09-06
|
||||
|
||||
### Changed
|
||||
|
||||
Generated
+3
-3
@@ -27,9 +27,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alkcall"
|
||||
version = "0.5.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bbaeb718c370b74f9136d1d59b4608249bd7d1dd2332c0259f98351d709737f"
|
||||
checksum = "8695d47cee5b5a5fe68471f04a505bc257a7e7ed9e64d827de33ff83adf4db12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -48,7 +48,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alkhttp"
|
||||
version = "0.2.0"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"alkcall",
|
||||
"arc-swap",
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "alkhttp"
|
||||
version = "0.2.0"
|
||||
version = "0.5.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "HTTP interface for the alk stack: serves HTTP/1.1 + HTTP/2 on standard ALPNs (with WebSocket upgrade carrying the channels protocol) and hosts the HTTP-backed call-protocol adapters"
|
||||
readme = "README.md"
|
||||
@@ -42,7 +42,7 @@ h2 = ["server", "dep:hyper", "hyper-util/http2", "hyper/http2"]
|
||||
http1 = ["server", "dep:hyper", "hyper-util/http1", "hyper/http1"]
|
||||
|
||||
[dependencies]
|
||||
alkcall = { version = "0.5", features = ["gateway"] }
|
||||
alkcall = { version = "0.8", features = ["gateway"] }
|
||||
arc-swap = { version = "1", optional = true }
|
||||
axum = { version = "0.8", optional = true, features = ["ws"] }
|
||||
bytes = "1"
|
||||
|
||||
@@ -161,7 +161,7 @@ A lean single-side build takes `default-features = false` plus the side
|
||||
it needs:
|
||||
|
||||
```toml
|
||||
alkhttp = { version = "0.2", default-features = false, features = ["server"] }
|
||||
alkhttp = { version = "0.5.0", default-features = false, features = ["server"] }
|
||||
```
|
||||
|
||||
## Security posture
|
||||
|
||||
@@ -4,21 +4,25 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (amended by alknet ADR-049 — protocol-level code list extended to six; alkcall ADR-021)
|
||||
Accepted (amended by alknet ADR-049 — protocol-level code list extended to six; alkcall ADR-021; alkcall 0.7.0 CF-007 — the list is eight: `ALREADY_EXISTS` (alkcall ADR-022, mapped 409 Conflict by review 006 UP-01) and `CONNECTION_CLOSED` (alkcall ADR-016 CF-001, mapped 503 Service Unavailable in this crate's gateway error table))
|
||||
|
||||
## Context
|
||||
|
||||
The `OperationSpec` in the call crate (now alkcall) has `input_schema` and
|
||||
`output_schema` but no `error_schemas`. The `call.error` payload (the alkcall
|
||||
crate's `call-protocol.md`) carries a `code` and `message`, where `code` is
|
||||
one of six infrastructure codes: `NOT_FOUND`, `FORBIDDEN`, `INVALID_INPUT`,
|
||||
`INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`.
|
||||
one of eight infrastructure codes: `NOT_FOUND`, `FORBIDDEN`, `INVALID_INPUT`,
|
||||
`INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`, `ALREADY_EXISTS`,
|
||||
`CONNECTION_CLOSED`.
|
||||
|
||||
These six codes cover **protocol-level failures** — the call protocol
|
||||
These eight codes cover **protocol-level failures** — the call protocol
|
||||
itself can always fail to find an operation, deny access, reject bad input,
|
||||
reject the wrong dispatch method for the operation type, time out, or hit
|
||||
an internal error. They are emitted by the dispatch machinery (the registry,
|
||||
the adapter), not by operation handlers. `INVALID_OPERATION_TYPE` was added
|
||||
reject the wrong dispatch method for the operation type, time out, hit an
|
||||
internal error, reject an `op/register` collision (`ALREADY_EXISTS`, alkcall
|
||||
ADR-022), or observe a provably-undelivered call (`CONNECTION_CLOSED`,
|
||||
alkcall ADR-016 CF-001 — the only retryable protocol code). They are emitted
|
||||
by the dispatch machinery (the registry, the adapter), not by operation
|
||||
handlers. `INVALID_OPERATION_TYPE` was added
|
||||
by alknet ADR-049 (streaming handler for subscriptions — now alkcall ADR-021;
|
||||
`invoke()` called on a `Sub`, or `invoke_streaming()` on a `Query`/`Mutation`).
|
||||
|
||||
@@ -173,8 +177,8 @@ optional-array convention.
|
||||
|
||||
- `code` — the error code. Either a protocol-level code (`NOT_FOUND`,
|
||||
`FORBIDDEN`, `INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`,
|
||||
`TIMEOUT`) or an operation-level domain code from `error_schemas` (e.g.,
|
||||
`FILE_NOT_FOUND`, `RATE_LIMITED`).
|
||||
`TIMEOUT`, `ALREADY_EXISTS`, `CONNECTION_CLOSED`) or an operation-level
|
||||
domain code from `error_schemas` (e.g., `FILE_NOT_FOUND`, `RATE_LIMITED`).
|
||||
- `message` — human-readable error message. Unstructured — for logging and
|
||||
debugging, not for programmatic handling. Consumers should switch on
|
||||
`code`, not parse `message`.
|
||||
@@ -190,8 +194,8 @@ optional-array convention.
|
||||
|
||||
### 3. Protocol-level vs operation-level error codes
|
||||
|
||||
The six existing codes are **protocol-level** — emitted by the dispatch
|
||||
machinery, not by handlers:
|
||||
The eight protocol-level codes are **protocol-level** — emitted by the
|
||||
dispatch machinery, not by handlers:
|
||||
|
||||
| Code | Emitted by | Meaning |
|
||||
|------|-----------|---------|
|
||||
@@ -201,6 +205,8 @@ machinery, not by handlers:
|
||||
| `INVALID_OPERATION_TYPE` | Registry / `OperationEnv` | Wrong dispatch path for the operation's type (`invoke()` on a `Sub`, `invoke_streaming()` on a `Query`/`Mutation`, `invoke_sink()` on a `Query`/`Mutation`/`Sub`, or `OperationEnv::invoke()` on a `Sub` during composition — alkcall ADR-021; `Pub` ops dispatch via `invoke_sink()`, alkcall ADR-046) |
|
||||
| `INTERNAL` | Registry / Adapter | Handler panic, unhandled error, connection failure |
|
||||
| `TIMEOUT` | Adapter | Request timed out |
|
||||
| `ALREADY_EXISTS` | Registry / collision gate | `op/register` collision — a peer-announced op may not replace the serving side's own registrations (alkcall ADR-022 G-03) |
|
||||
| `CONNECTION_CLOSED` | Client write path | The `call.requested` frame could not be written — the call is provably undelivered (alkcall ADR-016 CF-001). `retryable: true` — the only protocol code a caller may auto-retry. |
|
||||
|
||||
Operation-level domain codes are emitted by **handlers** — the operation's
|
||||
own logic determines what went wrong. They are declared in `error_schemas`
|
||||
@@ -251,9 +257,9 @@ accordingly.
|
||||
```
|
||||
|
||||
**Normative rule (review #002 W20)**: `from_openapi` must not produce error
|
||||
codes that collide with the six protocol-level codes (`NOT_FOUND`,
|
||||
codes that collide with the protocol-level codes (`NOT_FOUND`,
|
||||
`FORBIDDEN`, `INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`,
|
||||
`TIMEOUT`). The adapter prefixes
|
||||
`TIMEOUT`, `ALREADY_EXISTS`, `CONNECTION_CLOSED`). The adapter prefixes
|
||||
imported error codes with `HTTP_` and the status number (e.g., `HTTP_404`,
|
||||
`HTTP_429`) to avoid collision. This is a requirement for the adapter, not
|
||||
a naming convention — the `from_openapi` example above was previously shown
|
||||
|
||||
@@ -553,8 +553,9 @@ for the factoring recommendation (thin shared struct, not a trait).
|
||||
`from_openapi` maps OpenAPI non-2xx response status codes to
|
||||
`ErrorDefinition`s (alkcall ADR-016 §5). The normative rule (review
|
||||
#002 W20): `from_openapi` must not produce error codes that collide
|
||||
with the six protocol-level codes (`NOT_FOUND`, `FORBIDDEN`,
|
||||
`INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`). The
|
||||
with the protocol-level codes (`NOT_FOUND`, `FORBIDDEN`,
|
||||
`INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`,
|
||||
`ALREADY_EXISTS`, `CONNECTION_CLOSED`). The
|
||||
adapter prefixes imported error codes with `HTTP_` and the status
|
||||
number:
|
||||
|
||||
@@ -601,7 +602,7 @@ request-level cap failure (422; GW-16 unified it with the
|
||||
`INVALID_INPUT → 422` mapping — it was hand-rolled as 400 before
|
||||
review-002). `BatchResultEntry.error` references
|
||||
the `BatchError` component (review-002 PRJ-16b): the serialized
|
||||
`CallError` as a oneOf over the six protocol-code envelopes plus a
|
||||
`CallError` as a oneOf over the protocol-code envelopes plus a
|
||||
generic arm carrying the operation-declared codes. See alkcall ADR-016.
|
||||
|
||||
## Why
|
||||
|
||||
@@ -285,7 +285,15 @@ semantically-validating hook dials/prepares the backend before the
|
||||
reply, and a bounded failure resolves `channel:open_failed` with
|
||||
`details.reason` (the channel never exists consumer-side). The
|
||||
per-registration timeout override bounds the establisher when the
|
||||
dispatch carries no deadline. The `OpenableAlpns` request-extension
|
||||
dispatch carries no deadline. The establisher's `Establishment.plan`
|
||||
payload (alkcall 0.6.0 / ADR-049 amendment 2 — a typed-opaque
|
||||
`ChannelPlan`) is threaded process-locally to the pump handler's
|
||||
second parameter: the establisher and the handler agree on the
|
||||
concrete type, so ALPN crates dial/allocate in the establisher and
|
||||
deliver the live handle to their handler without a side-channel
|
||||
handoff. Data-plane handlers that pump a channel stream against a
|
||||
peer's split halves can use alkcall's `channels::pump_bidi` helper
|
||||
(alkcall 0.6.0 / ADR-050). The `OpenableAlpns` request-extension
|
||||
fallback is available for bare-registry/custom
|
||||
upgrade routes. Cap policy is the `ChannelsPolicy` extension (one
|
||||
instance consulted by both the open wrappers and the demux teardown).
|
||||
|
||||
@@ -2125,8 +2125,7 @@ mod tests {
|
||||
);
|
||||
assert!(
|
||||
!segments.iter().any(|s| s == "." || s == ".."),
|
||||
"value `{value:?}` must not leave lone dot segments: {:?}",
|
||||
segments
|
||||
"value `{value:?}` must not leave lone dot segments: {segments:?}"
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
|
||||
+27
-3
@@ -4,9 +4,11 @@
|
||||
//! (`NOT_FOUND`, `FORBIDDEN`, `INVALID_INPUT`, `INVALID_OPERATION_TYPE`,
|
||||
//! `TIMEOUT`, `ALREADY_EXISTS` — the seventh code, alkcall ADR-022's
|
||||
//! `op/register` collision policy, mapped 409 Conflict, review-006
|
||||
//! UP-01) map to fixed statuses; operation-level codes imported from
|
||||
//! external HTTP APIs are prefixed `HTTP_<status>` and map to their
|
||||
//! declared status.
|
||||
//! UP-01; `CONNECTION_CLOSED` — the eighth code, alkcall ADR-016's
|
||||
//! retryable undelivered-call code, mapped 503 Service Unavailable,
|
||||
//! alkcall 0.7.0's CF-007 amendment made the list formal) map to fixed
|
||||
//! statuses; operation-level codes imported from external HTTP APIs are
|
||||
//! prefixed `HTTP_<status>` and map to their declared status.
|
||||
//!
|
||||
//! The identity-aware variant maps the ambiguous protocol codes
|
||||
//! (`FORBIDDEN`, `INVALID_OPERATION_TYPE`) to `401` when no token
|
||||
@@ -30,6 +32,7 @@ const PROTOCOL_CODE_INVALID_INPUT: &str = "INVALID_INPUT";
|
||||
const PROTOCOL_CODE_INVALID_OPERATION_TYPE: &str = "INVALID_OPERATION_TYPE";
|
||||
const PROTOCOL_CODE_TIMEOUT: &str = "TIMEOUT";
|
||||
const PROTOCOL_CODE_ALREADY_EXISTS: &str = "ALREADY_EXISTS";
|
||||
const PROTOCOL_CODE_CONNECTION_CLOSED: &str = "CONNECTION_CLOSED";
|
||||
const PROTOCOL_CODE_INTERNAL: &str = "INTERNAL";
|
||||
|
||||
const HTTP_PREFIX: &str = "HTTP_";
|
||||
@@ -40,6 +43,7 @@ const STATUS_FORBIDDEN: u16 = 403;
|
||||
const STATUS_UNPROCESSABLE: u16 = 422;
|
||||
const STATUS_TIMEOUT: u16 = 504;
|
||||
const STATUS_CONFLICT: u16 = 409;
|
||||
const STATUS_SERVICE_UNAVAILABLE: u16 = 503;
|
||||
const STATUS_INTERNAL: u16 = 500;
|
||||
|
||||
const RETRY_AFTER_STATUSES: &[u16] = &[429, 503];
|
||||
@@ -77,6 +81,7 @@ pub fn call_error_to_http_status_with_identity(
|
||||
}
|
||||
PROTOCOL_CODE_TIMEOUT => STATUS_TIMEOUT,
|
||||
PROTOCOL_CODE_ALREADY_EXISTS => STATUS_CONFLICT,
|
||||
PROTOCOL_CODE_CONNECTION_CLOSED => STATUS_SERVICE_UNAVAILABLE,
|
||||
PROTOCOL_CODE_INTERNAL => STATUS_INTERNAL,
|
||||
code if code.starts_with(HTTP_PREFIX) => code[HTTP_PREFIX.len()..]
|
||||
.parse::<u16>()
|
||||
@@ -193,6 +198,25 @@ mod tests {
|
||||
assert_eq!(call_error_to_http_status(&error), 409);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_closed_maps_to_503() {
|
||||
let error = CallError::connection_closed("undelivered");
|
||||
assert_eq!(call_error_to_http_status(&error), 503);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connection_closed_carries_retry_after_when_details_present() {
|
||||
let error = CallError::connection_closed("undelivered")
|
||||
.with_details(serde_json::json!({ "retry_after": "5" }));
|
||||
let resp = call_error_to_http_response(&error);
|
||||
assert_eq!(resp.status(), 503);
|
||||
let retry_after = resp
|
||||
.headers()
|
||||
.get(header::RETRY_AFTER)
|
||||
.map(|v| v.to_str().unwrap().to_string());
|
||||
assert_eq!(retry_after.as_deref(), Some("5"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn internal_maps_to_500() {
|
||||
let error = CallError::internal("boom");
|
||||
|
||||
@@ -273,7 +273,10 @@ impl HttpAdapter {
|
||||
/// `channel_open` marker), the ALPN-specific
|
||||
/// [`OpenHandler`](alkcall::channels::operations::OpenHandler),
|
||||
/// and the optional establisher + per-registration timeout
|
||||
/// (ADR-049, threaded through with `None` defaults). Each WS
|
||||
/// (ADR-049, threaded through with `None` defaults). With an
|
||||
/// establisher attached, its `Establishment.plan` (alkcall 0.6.0 /
|
||||
/// ADR-049 amendment 2) is threaded process-locally to the pump
|
||||
/// handler's second parameter. Each WS
|
||||
/// session's per-session fork registers the set (plus the generic
|
||||
/// channel ops, bootstrap discovery, and `op/register`), so a WS
|
||||
/// client can open data channels exactly as any channels consumer
|
||||
|
||||
@@ -271,13 +271,24 @@ pub struct OpenableAlpn {
|
||||
/// per the upstream C-08 stub until channel adoption lands).
|
||||
pub spec: OperationSpec,
|
||||
/// The data-plane protocol handler spawned on the allocated
|
||||
/// channel's `Connection`.
|
||||
/// channel's `Connection` — `Fn(Value, Option<ChannelPlan>,
|
||||
/// Connection, AuthContext) -> JoinHandle<()>`. With an
|
||||
/// establisher attached, the plan (alkcall 0.6.0 /
|
||||
/// ADR-049 amendment 2) is the establisher's `Establishment.plan`:
|
||||
/// the establisher and the handler agree on the concrete type
|
||||
/// (downcast in the ALPN crate); `None` when no establisher is
|
||||
/// registered or it returned `Establishment::default()`
|
||||
/// (`alkcall::channels::operations::Establishment::default`).
|
||||
pub open_handler: OpenHandler,
|
||||
/// The awaited establishment phase (ADR-049 §1): validate params
|
||||
/// semantically, consult ownership, prepare/dial the backend —
|
||||
/// before the open reply. `None` (the default) = an always-OK
|
||||
/// establisher (the pre-ADR-049 shape; existing registrations
|
||||
/// behave unchanged).
|
||||
/// behave unchanged). A successful establisher returns
|
||||
/// `Establishment::new(plan)` (to deliver a channel plan to the
|
||||
/// pump handler) or `Establishment::default()` when it only
|
||||
/// validates — both in
|
||||
/// `alkcall::channels::operations`.
|
||||
pub establisher: Option<OpenEstablisher>,
|
||||
/// The per-registration bound on the establisher await
|
||||
/// (ADR-049 §2). `None` = [`ESTABLISHMENT_TIMEOUT`] (10s) when the
|
||||
|
||||
@@ -1057,7 +1057,7 @@ use alkcall::channels::operations::OpenHandler;
|
||||
/// payload) chunks; the handler reads the channel's BiStream and
|
||||
/// writes the echo — the exact data-plane shape ADR-067 promises.
|
||||
fn echo_open_handler() -> OpenHandler {
|
||||
Arc::new(move |_input, channel_conn, _auth| {
|
||||
Arc::new(move |_input, _plan, channel_conn, _auth| {
|
||||
tokio::spawn(async move {
|
||||
let mut stream = match channel_conn.accept_bi().await {
|
||||
Ok(s) => s,
|
||||
|
||||
Reference in New Issue
Block a user