Skip to content

v0.21.4

Choose a tag to compare

@rustyconover rustyconover released this 14 Aug 20:31
· 6 commits to main since this release
Immutable release. Only release title and notes can be modified.

Streaming clients over a persistent transport (pipe / subprocess / socket) now work.

Two defects on the client half of the streaming path, both reachable by any caller of a @StreamHeader stream over a non-HTTP transport:

  • The declared stream header was never consumed. resolveHeaderType looked for the header record in a second RpcStream type argument, but RpcStream<S extends StreamState> declares one type parameter — which is why @StreamHeader exists. ServiceIntrospector had already resolved the annotation into RpcMethodInfo.headerType(); nothing read it. The server writes the header stream whenever the annotation is present, so the client skipped it and decoded the header batch as the stream's first data batch.
  • close() hung after end-of-stream. It drained the output stream unconditionally, but once the producer signals EOS the server is back awaiting the next request, so the read blocked until the transport died. Since tick() calls close() on end-of-stream, a completed producer scan hung instead of returning.

Serving streams is unaffected, and the HTTP client path never had either bug — it reads headers through HttpStreamHandler. That is why both survived: streaming had only ever been client-tested over HTTP.

ClientStreamHeaderTest covers both over an in-process pipe pair; all four cases fail without the fixes.