Fixes the Pub operation's client→responder path so a publish() actually works on any transport. Previously the wire was broken in three compounding ways and the unit tests couldn't see it. P-01 [critical] — publish chunks were written to a *fresh* open_bi stream (stream B) while the responder read chunks from the stream that carried call.requested (stream A). Stream B's frames were silently discarded by the dispatch loop's "ignoring non-requested event" branch. On single-stream transports (TCP+TLS, SSH) the second open_bi returns StreamClosed outright, so every publish failed. Fix: pump call.requested + call.published + call.completed on the *same* write half via the new pump_publish_to_wire free function; the read half is pumped concurrently for the single call.responded. P-02 [major] — publish() / publish_with_payload() now take Pin<Box<dyn Stream<Item = Value> + Send>> per ADR-046 §8, not Vec<Value>. The Vec shape buffered the entire publish in memory and made the ADR's flagship use cases (telemetry ingest, live upload, drag-drop file streaming) impossible. The wire format is unchanged; this corrects API drift (no deployments exist). P-05 [major] — publish now registers with timeout: None (like subscribe), not DEFAULT_CALL_TIMEOUT (30s). A publish whose stream took >30s wall-clock got a spurious client-side TIMEOUT while the responder kept consuming. PendingEntry::Call.timeout is now Option<Instant> so the sweeper never evicts unbounded calls; all register_call callers updated (Some(...) for call(), None for publish()). P-08 [major] — the dispatch Pub branch re-implemented invoke_sink's not-found / visibility / ACL / handler-kind checks inline; invoke_sink was only ever called from its own tests. Any future fix in invoke_sink (e.g. the missing publish_schema validation, P-03) wouldn't reach the wire path. Fix: extract OperationRegistry::resolve_sink_handler (pub(crate)) as the single source of truth for the sink dispatch checks; both invoke_sink and Dispatcher::dispatch (Pub branch) call it. The two paths can no longer diverge. P-09 [major, side-effect] — make_sink_forwarding_handler in from_call.rs was store-and-forward (collect into Vec) and silently discarded Err items (filter_map(|item| item.ok())), contradicting the SinkHandler contract that an Err terminates the stream. Now that publish_with_payload takes a Stream, the forwarding handler passes the stream through directly (streamed, not buffered) and uses take_while(Ok) + filter_map to terminate on Err. P-09 was listed in Unit 6 but depends on P-01/P-02, so it falls out naturally here. P-12 #1 [acceptance gate] — adds the end-to-end publish test that the review identifies as the gate for this unit: publish_end_to_end_delivers_chunks_and_returns_response wires CallConnection::publish ↔ Dispatcher::run_loop over a real tokio::io::duplex pair (new duplex_connection_pair test helper + SingleStreamSource BidiStreamSource impl), publishes 3 chunks, and asserts the responder saw all 3 and returned the right result. A second test covers the unknown-op → NOT_FOUND path. These tests would have caught P-01 immediately. Verification: - cargo test --lib → 434 passed, 0 failed (was 432; +2 e2e tests) - cargo clippy --all-targets -- -D warnings → clean - cargo fmt --check → clean - cargo doc --no-deps → 4 warnings (pre-existing C-09, unchanged)
Description
No description provided
Languages
Rust
100%