refactor: hoist per-operation exceptionMetadataMapper to client field - #7240
Open
zoewangg wants to merge 1 commit into
Open
refactor: hoist per-operation exceptionMetadataMapper to client field#7240zoewangg wants to merge 1 commit into
zoewangg wants to merge 1 commit into
Conversation
The JSON-family protocols emitted a byte-identical exceptionMetadataMapper lambda into every non-streaming operation body. It switches over the whole service model's exceptions with no per-operation input, so hoist it to a single per-client field. Removes duplicated bytecode and source without changing runtime behavior. Re-seed ClientLambdaCallSiteCeilingTest ceilings for the json/cbor/rpcv2/ aws-json fixtures down to the post-hoist counts, since each non-streaming operation no longer carries an inline mapper lambda.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
For the JSON-family protocols (AWS JSON, REST JSON, CBOR, Smithy RPC v2), the code generator emitted a
Function<String, Optional<ExceptionMetadata>> exceptionMetadataMapperlambda into every non-streaming operation body of the generated sync and async clients. That lambda is aswitchover the service model's exception shapes.The mapper does not vary per operation: it is built by iterating the whole service model's exception list (
model.getShapes()filtered to exceptions), with no operation-specific input. So every operation of a client generated a byte-identical copy of the same switch. For a large JSON client this duplicates a big switch into every operation body, inflating generated source, compiled bytecode, and the packaged jar. It also emits one extra lambda call site per operation, which contributes to the per-class constant pool that large clients accumulate.This mirrors the metric-lambda reduction in #7226, which hoisted the per-operation metric-publishing lambdas into shared helpers for the same reason.
The packaged-jar reduction is much smaller than the raw
.classreduction because the duplicatedswitchcompresses very well under the jar's DEFLATE, so the large uncompressed win shrinks once packaged.Modifications
Hoist the non-streaming
exceptionMetadataMapperout of every operation body into a single per-client field, for the four JSON-family protocols, in both the sync and async generated clients.ProtocolSpecgains adefault Optional<FieldSpec> errorResponseMapperField()returning empty. Query, REST-XML and EC2 inherit the empty default and are unchanged (they register modeled exceptions on the protocol factory at init time and emit no per-operation mapper).JsonProtocolSpecoverrideserrorResponseMapperField()to build the whole-model switch once as aprivate finalfield, and itserrorResponseHandler(...)now emits only the one-linecreateErrorResponseHandler(..., exceptionMetadataMapper)referencing that field.SyncClientClass/AsyncClientClassadd the field to the generated client when the protocol provides one.Scope and invariants:
eventstreamExceptionMetadataMapperemitted in event-stream operation bodies is left inline: it iterates that operation's event-stream error members, so it genuinely varies per operation and is not hoistable.BaseAwsJsonProtocolFactory.createErrorResponseHandler(JsonOperationMetadata, Function)overload toAwsJsonProtocolErrorUnmarshallerexactly as before. The error code is parsed off the wire and looked up in the mapper identically; unmodeled codes still fall back to the default service exception. Behavior is identical for the same error code.Default<Svc>[Async]Clientis a package-privatefinalclass; no public, protected, or SdkInternalApi type changes.Testing
Updated tests
Types of changes
Checklist
mvn installsucceedsscripts/new-changescript and following the instructions. Commit the new file created by the script in.changes/next-releasewith your changes.License