feat(middleware-user-agent): cache user agent string #3970
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.
Cache the user agent string after the first successful computation. Do this in a way that ensures
await
isn't called in the middleware if the user agent is already computed (run middleware in single tick).Middleware such as the user agent is called on every single call to aws, so for dbs (e.g. fetching single keys), the middleware should in principle be memory/cpu efficient.
Additionally, this would mitigate issues similar to #2027 for any clients with different implementations of defaultUserAgentProvider (in the future, since that issue was already fixed) (if those implementations read files, make service calls, etc)
Context: I saw that client-dynamodb calls took twice as long to resolve, and cpu usage was slightly higher after switching from aws-sdk, even after the fix for #2223. The impact on dynamodb promise resolution times was higher at peak load when Node.js was using more cpu per process. (The Node.js process had around 40% cpu usage)
Avoid extra cpu from calling map, defaultUserAgentProvider+await, etc.
As a result of 388b180 switching from defaultUserAgent to defaultUserAgentProvider, the middleware would have to recompute the user agent on every single api call. This fixes that by computing the user agent only once, when the middleware is instantiated. (So creating a client but not using it will now call this, but creating a client has overhead anyway)
Issue
Issue number, if available, prefixed with "#"
Description
Reduces cpu overhead of recomputing user agent on every created http request, avoid an await that would postpone
work until the next cpu tick
Testing
How was this change tested?
TODO:
Are there benchmarks comparing time to resolve promises for concurrent calls with aws-sdk (monolithic v2) and aws-sdk-js-v3? (I saw worse response times in APIs after switching from aws-sdk to aws-sdk-js-v3 with dynamodb client for get/set in April 2021, despite doing the same operations)
Or are there tickets to create these benchmarks?
Optionally, Write a short script to benchmark calls per second and cpu per call with realistic user agent values?
Verify that middleware calls next() in the same tick
Additional context
Add any other context about the PR here.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.