Skip to content

Add support for initial-response event streams on servers#4352

Merged
rcoh merged 8 commits intomainfrom
send-initial-response
Oct 20, 2025
Merged

Add support for initial-response event streams on servers#4352
rcoh merged 8 commits intomainfrom
send-initial-response

Conversation

@rcoh
Copy link
Collaborator

@rcoh rcoh commented Oct 16, 2025

Motivation and Context

Event Stream operations over RPC protocols (that do not rely on HTTP headers), use initial-request and initial-response objects to send data fields that are not bound to the event stream itself.

However, there are two major bug in the current implementation:

Description

This adds two things:

  1. Optional (and disabled by default) sending of an initial-response message in all cases (even when the resulting message would be empty). Servers that communicate with smithy-java clients MUST enable this setting currently. This is disabled by default because clients in the wild today do not accept an empty initial-response.
  2. Support for sending non-empty initial response messages

Testing

  • Extensive unit testing

Checklist

  • For changes to the smithy-rs codegen or runtime crates, I have created a changelog entry Markdown file in the .changelog directory, specifying "client," "server," or both in the applies_to key.
  • For changes to the AWS SDK, generated SDK code, or SDK runtime crates, I have created a changelog entry Markdown file in the .changelog directory, specifying "aws-sdk-rust" in the applies_to key.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@rcoh rcoh added the server Rust server SDK label Oct 16, 2025
@rcoh rcoh requested review from a team as code owners October 16, 2025 13:16
@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@rcoh rcoh requested review from drganjoo and ysaito1001 October 16, 2025 16:28
""",
*codegenScope,
) {
rustTemplate("let mut headers = #{Vec}::new();", *codegenScope)
Copy link
Contributor

Choose a reason for hiding this comment

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

Worth a with_capacity()?

Copy link
Contributor

Choose a reason for hiding this comment

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

If so, renderInitialRequestGenerator above (hidden in collapsible section in diff) may benefit, too.


⚠️ **Footgun**: Name collisions mean only one implementation gets generated.

## GitHub CLI Integration
Copy link
Contributor

Choose a reason for hiding this comment

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

Feel like since this section isn't project specific it should live somewhere more generic for the agent rather than in the AGENTS file of each project?

Copy link
Contributor

@ysaito1001 ysaito1001 left a comment

Choose a reason for hiding this comment

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

Thanks for fixing the client-side bug

""",
*codegenScope,
) {
rustTemplate("let mut headers = #{Vec}::new();", *codegenScope)
Copy link
Contributor

Choose a reason for hiding this comment

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

If so, renderInitialRequestGenerator above (hidden in collapsible section in diff) may benefit, too.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@rcoh rcoh force-pushed the send-initial-response branch from bb24c90 to 5f5dd0d Compare October 17, 2025 19:14
@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

events: Events
}

structure StreamingOperationWithInitialResponseOutput {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add an operation with optional fields to future-proof our tests? Smithy specs state: "Clients and servers MUST NOT fail if an initial-request or initial-response is not received for an initial message that contains only optional members." This would help test our handling of this requirement when we implement client support.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah I'll add that to the model. There are a couple of other small improvements to make to the tests here, I'll open a tickets:

  1. Make it possible to use a generated client (not just the manually implemented one)
  2. Make it possible to actually generate these tests to make it easy to run them against multiple protocols.

}
}

fun renderInitialResponseGenerator(contentType: String): RuntimeType {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this functionality server-specific? If so, shouldn't we move it out of the core module and keep it only in server-related modules?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you could do that for ideological reasons, but all the library functions it needs are in here so its cleaner IMO

CodegenTest(
"smithy.protocoltests.rpcv2Cbor#RpcV2CborService",
"rpcv2Cbor_extras_no_initial_response",
imports = listOf("$commonModels/rpcv2Cbor-extras.smithy"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have tests for other protocols? or are we only implementing this for rpcv2Cbor for now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

its implemented for all protocols but currently only tested with cbor.

@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

rcoh added 8 commits October 20, 2025 19:17
Unexpected and contrary to documentation, clients do not currently always accept initial responses. This fixes that issue and updates clients to
always accept initial responses for event streams.

Because of this, we must also change the default to `false` for the setting to avoid backwards compatibility issues with existing clients.
@rcoh rcoh force-pushed the send-initial-response branch from 50c9b02 to 21656e5 Compare October 20, 2025 23:17
@rcoh rcoh enabled auto-merge (squash) October 20, 2025 23:18
@github-actions
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@rcoh rcoh merged commit f4a2672 into main Oct 20, 2025
50 checks passed
@rcoh rcoh deleted the send-initial-response branch October 20, 2025 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client server Rust server SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

client does not accept unexpected initial-response on event streams servers must send initial-response in all cases

4 participants