Skip to content

92 - adding stream support for lists - #94

Open
tomsontom wants to merge 34 commits into
mainfrom
92-add-streaming-support-for-lists
Open

92 - adding stream support for lists#94
tomsontom wants to merge 34 commits into
mainfrom
92-add-streaming-support-for-lists

Conversation

@tomsontom

Copy link
Copy Markdown
Member
  • extended language to support @stream in the return-types
  • added streaming-property to model

@tomsontom tomsontom linked an issue Aug 5, 2026 that may be closed by this pull request
@tomsontom

Copy link
Copy Markdown
Member Author

Automated review (Claude)

Reviewed the diff across grammar, generators, and generated Java/TypeScript clients. 22 findings, grouped by severity.

Correctness — likely bugs

  1. msgpack streaming is silently corrupted. response-builder.ts:80encodeAsJsonArray(!$contentType.equals("application/json")) is inverted: it wraps msgpack streams in JSON array framing ([, ,, ]) and leaves JSON streams unwrapped — backwards from the newline-delimited-JSON / raw-concatenated-msgpack framing this PR establishes elsewhere. Those bracket/comma bytes are valid msgpack fixints, so the client's unpacker.hasNext() loop won't throw — it silently misinterprets them as extra bogus values interleaved with real records.

  2. Compile error: void method returns a void-typed call. json-utils.ts:437 — for projects with a single content-type encoding, generated _JsonUtils.decodeStream(...) (declared void) contains return decodeJsonStream(stream, consumer); where decodeJsonStream is itself void. Illegal in Java. Not caught by this PR's tests because both test specs configure two encodings and take a different branch.

  3. Compile error: missing return/throw for streaming ops with explicit REST result codes. service.ts:861generateResponseDispatchStream's per-status-code if blocks have no trailing return/throw after the loop, unlike the non-streaming dispatch. Not exercised because no streaming op in the test spec declares explicit REST results.

  4. Generated TS client fails tsc --strict. fetch-type-utils.ts:299-347 — confirmed by running tsc --strict on the generated fixture: TS2504 (ReadableStream<Uint8Array> isn't declared AsyncIterable under DOM lib) and TS2345 (re-declared stream re-reads response.body instead of the already-narrowed outer binding, losing the null-check). Invisible in this repo's own CI since the CLI package's build step is a no-op and Vitest only transpiles.

  5. Transport errors reported to the client as success. response-utils.ts:348-360StreamSubscriber.onError(Throwable t) discards t and just closes the pipe; the decode thread's finally block then always signals a clean completion regardless of whether the stream ended normally or via a dropped connection. Callers can't detect a truncated stream.

  6. @Produces dropped for the whole resource class if any operation streams. resource.ts:81 — the guard is keyed on s.operations.some(...) (per-service), not per-operation, so one streaming operation silently disables JAX-RS content-negotiation/406 handling for every non-streaming sibling operation in the same resource. Flagged independently by 4 separate review passes.

  7. Streaming onSuccess called with null responseAdapter. service.ts:826 — contradicts the LifecycleHook.onSuccess JavaDoc, which documents the adapter as always available to read headers/status. Any hook that calls .adapt(...) there will NPE for streaming operations.

  8. Streaming onSuccess bypasses the safeExecute error guard (TS). service.ts:910 — non-streaming calls wrap the onSuccess hook in safeExecute (catches/logs exceptions); the streaming branch calls it unguarded, turning a throwing hook into an unhandled promise rejection.

  9. (Lower confidence) onNext write failure never closes the pipe. response-utils.ts:335 — if the reader side is still alive when a write fails, the decode thread can block forever on in.read(), hanging the client call.

  10. Minor: stray § character leaked into the streaming error message at service.ts:901 ("...operation §${o.name}").

Efficiency

  • Per-element encoder/packer allocation on the server. _JsonUtils.java:1080encodeJsonValue/encodeMsgPackValue allocate a fresh StringWriter+JsonGenerator or MsgpackJson+MessageBufferPacker per streamed element via Multi.map(), instead of reusing one encoder for the whole stream.
  • Per-element parser allocation on the client. _JsonUtils.java:2294decodeJsonStream creates a new StringReader+JsonReader per element instead of one reusable streaming parser.
  • Per-chunk byte[] copy in the HTTP subscriber. response-utils.ts:313 — every ByteBuffer is copied into a fresh byte[] instead of a reusable scratch buffer.

Reuse / duplication

  • New mapLiteral helper not used by its own siblings. json-utils.ts:1194 — six new mapXxx(JsonValue) methods hand-roll the same instanceof/exception logic that the newly-added generic mapLiteral helper already provides.
  • handleOkResult duplicates its dispatch chain for streaming vs. array results. service.ts:819 — flagged independently by three review passes.
  • toResultType/toAPIResultType patched identically in two files. java-client-api/service.ts:134 — already-duplicate functions both got the same new logic hand-applied instead of being factored into java-gen-utils.ts.
  • Response-builder duplicates its encode chain per variant. response-builder.ts:67 — the sibling client-side generator in the same PR already shows the correct single-template pattern this file didn't follow.
  • Grammar duplicates the typeRef/inlineEnum match for streaming. remote-service-definition.langium:103streaming is added as a third top-level alternative instead of an optional flag on the existing rule.

Minor / cleanup

  • Dead TypeInfo<?> typeInfo parameter threaded through streamSubscriber/decodeStream but always null and never forwarded (response-utils.ts:298).
  • Unused Duration import + commented-out delay code in StreamRecordHandlerImpl.java:5.
  • Doubled "Handler" in generated class name StreamShortHandlerHandlerImpl.
  • Unused mutiny dependency added to the plain-JDK java-client module's pom.xml (likely meant for java-quarkus).

Generated by an automated review pass (Claude Code); please verify before acting on any finding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add streaming support for lists

1 participant