Skip to content

[WIP] Add SSE support to Java emitter - #12312

Draft
Xiaofei Cao (XiaofeiCao) wants to merge 34 commits into
microsoft:mainfrom
XiaofeiCao:xiaofeicao-java-sse-experimental
Draft

Xiaofei Cao (XiaofeiCao) wants to merge 34 commits into
microsoft:mainfrom
XiaofeiCao:xiaofeicao-java-sse-experimental

Conversation

@XiaofeiCao

@XiaofeiCao Xiaofei Cao (XiaofeiCao) commented Oct 20, 2026 •

Copy link
Copy Markdown
Member
  • Add typed SSE support for named, nonliteral JSON events in Azure v1 data-plane clients.
  • Generate async Flux<Event> and sync CloseableIterableStream<Event> APIs with typed event wrappers.
  • Decode model, scalar, array, and dictionary payloads, including nested collections and @data extraction.
  • Support terminal events and unknown event names, with incremental parsing, cancellation, and resource cleanup.
  • Preserve existing binary protocol APIs and version-specific overloads.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • ✅ @typespec/http-client-java
Show changes

@typespec/http-client-java - feature ✏️

Add support for named JSON server-sent events (SSE) in Azure-v1 data-plane convenience APIs.,> ,> tsp,> @events,> union Events {,> message: string,,> ,> @terminalEvent,> completed: string,,> },> ,> op stream(): SSEStream<Events>;,>

@XiaofeiCao
Xiaofei Cao (XiaofeiCao) marked this pull request as draft October 20, 2026 12:15
@XiaofeiCao Xiaofei Cao (XiaofeiCao) changed the title Add experimental SSE support to Java emitter [WIP]Add experimental SSE support to Java emitter Oct 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved generation failures, API visibility and module-export defects, and fixture-regeneration errors block approval.

6 open issues
What changed in this PR

Adds opt-in, experimental server-sent event (SSE) support to the Java emitter’s Azure flavor.

Changes:

  • Transfers SSE metadata into generated event wrappers, converters, and synchronous/asynchronous APIs.
  • Adds incremental parsing, response validation, and stream cleanup.
  • Adds generation fixtures, runtime tests, and changelog entries.
File Description
packages/​http-client-java/​generator/​http-client-generator/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​TypeSpecPlugin.java Wires SSE settings and helper generation.
packages/​http-client-java/​generator/​http-client-generator/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​model/​DevOptions.java Reads the experimental flag.
packages/​http-client-java/​generator/​http-client-generator-test/​tsp/​sse.tspconfig.yaml Enables SSE fixture generation.
packages/​http-client-java/​generator/​http-client-generator-test/​tsp/​sse.tsp Defines the integration fixture.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​test/​java/​tsptest/​sse/​models/​implementation/​sse/​ServerSentEventStreamTests.java Tests parsing and stream lifecycle.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​test/​java/​tsptest/​sse/​generated/​SseClientTestBase.java Adds generated client test setup.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​resources/​tsptest-sse.properties Supplies fixture SDK metadata.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​resources/​META-INF/​tsptest-sse_metadata.json Records generated fixture mappings.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​stream/​models/​TestStreamEvent.java Adds the generated event base.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​stream/​models/​TestStartedStreamEvent.java Wraps started-event payloads.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​stream/​models/​TestCompletedStreamEvent.java Wraps terminal-event payloads.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​stream/​implementation/​TestStreamEventConverter.java Converts fixture event payloads.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​SseClientBuilder.java Builds fixture clients.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​SseClient.java Demonstrates synchronous streaming APIs.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​SseAsyncClient.java Demonstrates asynchronous streaming APIs.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​package-info.java Documents the client package.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​models/​StartedPayload.java Adds the started payload model.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​models/​package-info.java Documents the payload package.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​models/​implementation/​sse/​ServerSentEventStreams.java Adds the generated runtime facade.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​models/​implementation/​sse/​ServerSentEventStreamResponse.java Adds generated response validation.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​models/​implementation/​sse/​ServerSentEventStream.java Adds the generated stream parser.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​models/​CompletedPayload.java Adds the completed payload model.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​implementation/​StreamOperationsImpl.java Implements fixture HTTP operations.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​implementation/​SseClientImpl.java Holds fixture client infrastructure.
packages/​http-client-java/​generator/​http-client-generator-test/​src/​main/​java/​tsptest/​sse/​implementation/​package-info.java Documents the implementation package.
packages/​http-client-java/​generator/​http-client-generator-test/​Generate.ps1 Selects the SSE fixture configuration.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​test/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​util/​SseNamingResolverTests.java Tests names and collisions.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​test/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​util/​SseMetadataRegistryTests.java Tests metadata deduplication and collisions.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​test/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​model/​javamodel/​JavaPackageSseTests.java Tests generated files and package placement.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​test/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​mapper/​ClientMethodMapperTests.java Tests SSE generation modes.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​resources/​ServerSentEventStreams.java Defines the runtime facade template.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​resources/​ServerSentEventStreamResponse.java Defines response validation and cleanup.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​resources/​ServerSentEventStream.java Defines incremental parsing and consumption.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​util/​TemplateUtil.java Marks SSE methods as collection-returning.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​util/​SseUtil.java Centralizes SSE package placement.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​util/​SseNamingResolver.java Resolves event and converter names.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​util/​SseMetadataRegistry.java Deduplicates streams and checks names.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​SseEventModelTemplate.java Generates typed event wrappers.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​SseEventConverterTemplate.java Generates JSON event converters.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​ConvenienceSyncMethodTemplate.java Generates synchronous stream calls.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​ConvenienceMethodTemplateBase.java Adds SSE helper imports.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​ConvenienceAsyncMethodTemplate.java Generates asynchronous stream calls.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​model/​javamodel/​JavaPackage.java Emits SSE files with collision checks.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​model/​clientmodel/​GenericType.java Models closeable stream return types.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​model/​clientmodel/​ClientMethodType.java Adds SSE method kinds.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​model/​clientmodel/​ClientMethod.java Carries SSE metadata through methods.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​model/​clientmodel/​ClassType.java Registers the closeable stream class.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​mapper/​ClientMethodMapper.java Maps operations to SSE methods.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​extension/​plugin/​JavaSettings.java Stores the SSE enablement setting.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​extension/​model/​codemodel/​SseMetadata.java Represents stream metadata.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​extension/​model/​codemodel/​SseEventMetadata.java Represents individual event metadata.
packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​extension/​model/​codemodel/​Operation.java Attaches SSE metadata to operations.
packages/​http-client-java/​emitter/​test/​fixtures/​sse.tsp Covers supported and protocol-only operations.
packages/​http-client-java/​emitter/​test/​fixtures/​sse-unsupported.tsp Covers unsupported payload fallback.
packages/​http-client-java/​emitter/​test/​code-model.test.ts Tests opt-in metadata and fallback behavior.
packages/​http-client-java/​emitter/​src/​options.ts Defines the experimental SSE option.
packages/​http-client-java/​emitter/​src/​lib.ts Adds the unsupported-stream diagnostic.
packages/​http-client-java/​emitter/​src/​common/​operation.ts Defines TypeScript SSE metadata contracts.
packages/​http-client-java/​emitter/​src/​code-model-builder.ts Processes upstream SSE metadata.
.chronus/​changes/​xiaofeicao-implement-sse-naming-2026-9-20-15-3-28.md Records naming centralization.
.chronus/​changes/​http-client-java-experimental-sse-2026-10-20.md Documents the experimental feature.

Review effort: Balanced

@azure-sdk-automation

azure-sdk-automation Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@JoshLove-msft

Copy link
Copy Markdown
Contributor

add opt-in Azure-flavor generation for named JSON server-sent event streams behind dev-options.enable-sse

Curious why this is opt-in rather than just enabled?

@XiaofeiCao

Copy link
Copy Markdown
Member Author

Curious why this is opt-in rather than just enabled?

Since we already had SSE customization code for Search GA Java SDK, my initial gut feeling is that we don't do major emitter changes before Search GA release.
Though current generated code is almost identical without customization, guess I could remove this opt-in once this PR's mature.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
@XiaofeiCao
Xiaofei Cao (XiaofeiCao) force-pushed the xiaofeicao-java-sse-experimental branch from f82f557 to c156bc1 Compare October 26, 2026 10:07
Copilot AI balanced review requested due to automatic review settings October 26, 2026 10:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preserve internal visibility and sync-over-async protocol names, export SSE event packages, and generate valid event names and datetime imports.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 26, 2026 10:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

2 open issues
2 previously missed issues

In code that hasn't changed since last review

Medium severity Reject named events with non-JSON payload content types

packages/​http-client-java/​emitter/​src/​code-model-builder.ts:1292

This accepts named events without checking event.payloadContentType, including string payloads explicitly marked @contentType("text/plain") (supported by packages/events/lib/decorators.tsp:41). Their unquoted SSE data is then passed to JsonProviders.createReader by SseEventConverterTemplate.java:146, so valid streams fail decoding; reject non-JSON payload content types through the existing unsupported-stream diagnostic and retain the raw APIs.

Medium severity Generate stream callbacks from wire types before client conversion

packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​SseEventConverterTemplate.java:131

Calling getClientType() before generating the JSON callback discards wire encodings: a seconds-encoded duration maps to Duration and is decoded with Duration.parse(...) rather than reading the numeric seconds (PrimitiveMapper.java:113–126, ClassType.java:466), so valid payloads fail during iteration, including inside collections. Generate callbacks from the mapped wire type and then convert the decoded value to its client type, as StreamSerializationModelTemplate.java:1564–1599 does.

6 resolved since last review

Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 26, 2026 12:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Preserve wire encodings during event deserialization

packages/​http-client-java/​generator/​http-client-generator-core/​src/​main/​java/​com/​microsoft/​typespec/​http/​client/​generator/​core/​template/​SseEventConverterTemplate.java:135

Calling getClientType() before building the JSON callback discards wire encodings: for example, a seconds-encoded duration becomes Duration and generates Duration.parse(reader.getString()), which fails on a valid numeric SSE payload such as 42. Deserialize using the wire type and then apply its client conversion (as WireTypeClientTypeConverter.java:105–120 does), recursively for collection elements, or retain the raw API for these encodings.

2 resolved since last review

Review effort: Balanced

Transport SSE definitions by union CID and bind canonical references before Java mapping. Emit only mapped definitions, preserve named output, and generate direct unnamed payloads or typed mixed and primitive-literal wrappers with strict matching and inclusive termination.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 26, 2026 17:02
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 29, 2026 10:20
Resolve the code-model constructor conflict by preserving main's structural-key scope guard together with SSE's safe mapping-node checks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Copilot AI balanced review requested due to automatic review settings October 29, 2026 10:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Validate SSE stream eligibility before enforcing generic union ownership, and restrict typed SSE convenience mapping to data-plane clients.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 29, 2026 12:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Generate typed SSE models through schema-local metadata and the ordinary model, mapper, package, and module workflow while keeping CodeModel passive and admission scoped to actual consuming clients.

Preserve binary fallback for unsupported streams and target fallback diagnostics at authored operations so operation and service suppression work under warning-as-error.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 31, 2026 08:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Preserve the reviewed SSE model workflow while incorporating main's experimental metadata and YAML constructor updates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Copilot AI balanced review requested due to automatic review settings October 31, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@XiaofeiCao

Copy link
Copy Markdown
Member Author

SSE naming-collision limitations

The remaining naming collisions are acknowledged and deferred from this PR. Resolving their review threads records that scope decision; it does not mean all colliding inputs now generate compilable Java.

The table summarizes the recorded investigation, not a newly executed collision matrix. Rarity is a qualitative estimate from the required naming combinations, not measured frequency. Rows are ordered by rarity category; ties are not ranked.

Case Scenario Possible collision names Outcome Estimated rarity
Stream container / request DTO A request model shares a stream container's name, conflicting with stream return/error-path references in the same client, including across different operations. Flux, CloseableIterableStream Compile failure Uncommon: requires a matching model name in the affected SSE client.
JDK date / payload DTO A payload model shares the JDK date type's name and is combined with plainDate decoding, producing ambiguous references in the base envelope or serializer, including nested collections. LocalDate Compile failure Uncommon: requires both the date-named model and date decoding in the affected source.
Runtime helper / request DTO A request model shares an SSE runtime helper's simple name, producing conflicting client imports and calls. ServerSentEventStreamHelper Compile failure Rare: requires an exact helper/model name match.
Serializer / request DTO A request model matches a generated per-stream serializer name, producing conflicting client imports and calls. Stream-derived serializer names, e.g. SomeEventSerializer Compile failure Rare: requires an exact stream-derived serializer/request name match.
Serializer / payload DTO A payload model matches its generated serializer; for example, the payload of SomeEvents is named like that stream's serializer. SomeEventSerializer Compile failure Rare: requires a payload to match its stream-derived serializer name.
Names exempt from deduplication In Azure-branded generation, TypeSpec namespaces starting with Azure. skip automatic name deduplication. An ordinary model and an SSE envelope retain the same name, which the mapper rejects. Ordinary SkippedEvent and the generated base envelope for SkippedEvents Generation failure Rare: requires both an exempt namespace and matching ordinary/envelope names.

"Exempt from deduplication" means names are not automatically given distinct suffixes, not that those models are excluded from generation.

The same deferred scope includes the cross-package event/request and event/payload clashes raised in the review (TestStreamEvent, AzureCollisionEvent), whether an existing mapper guard rejects a particular input before rendering or conflicting simple-name imports would otherwise prevent compilation. This table is not exhaustive. A general solution would need to reconcile complete client and model import sets, nested helper names, and qualified references—not just allocate distinct synthetic schema names.

In the recorded cases, conflicting inputs failed during generation or generated-Java compilation; none was observed to pass both stages with incorrect bindings or silently fall back to binary. Noncolliding, ordinary-deduplication, and normalized-name controls passed with the intended bindings. Those observations are not guarantees for untested inputs.

Addressed separately: commit 07568108fb908675f60d3d1c0e543d4efc1d0eba renamed the per-stream nested ConstructorAccessor to SseEventConstructorAccessor. Focused generated-compilation and decoding regressions cover the original ConstructorAccessor payload and independent stream registration. This is a bounded fix, not a general uniqueness guarantee; matching the new nested name remains a potential collision.

Previously working input regressions, incorrect bindings that survive compilation, silent naming-triggered binary fallback, and broken deduplication controls remain actionable defects rather than being dismissed by this deferral.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Generated public return-type changes and SSE stream cleanup contracts require maintainer validation against real sync/async transports and generated clients, which could not be exercised in this dependency-free review environment.

No open issues 🎉

Review effort: Balanced

This branch has not been deployed

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

Labels

emitter:client:java Issue for the Java client emitter: @typespec/http-client-java

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants