Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add socketTimeout to HTTP client config for closing stale connections #683

Merged
merged 7 commits into from
Mar 22, 2024

Conversation

sichanyoo
Copy link
Contributor

@sichanyoo sichanyoo commented Mar 14, 2024

Issue #

awslabs/aws-sdk-swift#1349

Companion PR: awslabs/aws-sdk-swift#1413

Description of changes

  • Adds a new config socketTimeout, which gets used to construct HTTPMonitoringOptions for CRTClientEngine. Sets the maximum time to wait between data packets, which is used to close stale connections.
  • Fixes URLSessionHTTPClient to use socketTimeout for its timeoutIntervalForRequest config instead of connectTimeout. Refer to this official doc form Apple, which confirms that timeoutIntervalForRequest maps to the new socketTimeout rather than connectTimeout, which is a connection timeout config.
  • Adds missing continuation.resume() that makes the application hang when socket timeout error is thrown.
  • Misc. comment change for clarification on what connectTimeout actually is for. It's not a socket timeout for limiting stale connections. It's used to limit time it takes to obtain a live connection to the server.

Prerequisite

  • Blocked on the aws-crt-swift PR: Fix MonitoringOptions awslabs/aws-crt-swift#242, which makes initializer for HTTPMonitoringOptions public for usage in smithy-swift.
  • Blocked on bumping aws-crt-swift version to the new release that contains changes from above PR.

Testing

Tested against localhost that mocks DynamoDB & does not return a response. HTTP client connection now closes and recovers from no server response as it should, instead of hanging for eternity.

Scope

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Sichan Yoo added 3 commits March 14, 2024 12:29
…stream in CRTClientEngine in HTTPMonitoringOptions constructor. Update comments to clarify the preexisting connetTimeout config's usage. Fix URLSession client to use the new socketTimeout config for timeoutIntervalForRequest instead of connectTimeout.
…alizers. Instead, use 0 (no socket timeout) if it was not provided by end-user in the config.
Copy link
Contributor

@jbelkins jbelkins left a comment

Choose a reason for hiding this comment

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

Technically this looks good. But we need to make sure through doc comments on the related config properties that customers understand what fields have what effect on the two supported HTTP clients.

@@ -338,6 +346,7 @@ public class CRTClientEngine: HTTPClient {
response.statusCode = makeStatusCode(statusCode)
case .failure(let error):
self.logger.error("Response encountered an error: \(error)")
continuation.resume(throwing: error)
Copy link
Contributor

Choose a reason for hiding this comment

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

good catch

/// Used to close stale connections that have no activity.
///
/// If no value is provided, the defaut client won't have a socket timeout.
public var socketTimeout: TimeInterval?
Copy link
Contributor

Choose a reason for hiding this comment

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

URLSession does not have separate settings for timeout on initial connection, and for idle time between data transmissions on an existing connection.

https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1408259-timeoutintervalforrequest

seems to be the setting for both and the two cannot be set individually.
Our doc comments should make clear which settings apply to which HTTP client and which are ignored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Found a separate setting for initial connection timeout in URLRequest: https://developer.apple.com/documentation/foundation/urlrequest/2011509-timeoutinterval/

connectTimeout config on HttpClientConiguration is now set for URLRequest:timeoutInterval.

if let connectTimeout = httpClientConfiguration.connectTimeout {
config.timeoutIntervalForRequest = connectTimeout
if let socketTimeout = httpClientConfiguration.socketTimeout {
config.timeoutIntervalForRequest = socketTimeout
Copy link
Contributor

Choose a reason for hiding this comment

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

See my note above. How we transfer the HTTP config fields to specific clients should be made clear in the doc comments.

Copy link
Contributor Author

@sichanyoo sichanyoo Mar 22, 2024

Choose a reason for hiding this comment

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

Both config fields are now used for same purposes in both clients, so I think existing comments do their job without exposing arbitrary details. Lmk if you think otherwise, as I may be missing something.

@sichanyoo sichanyoo merged commit 359a22b into main Mar 22, 2024
12 checks passed
@sichanyoo sichanyoo deleted the feat/socket-timeout-http-client branch March 22, 2024 21:04
@sichanyoo sichanyoo restored the feat/socket-timeout-http-client branch March 22, 2024 21:04
@sichanyoo sichanyoo deleted the feat/socket-timeout-http-client branch March 22, 2024 21:08
AndrewFossAWS pushed a commit that referenced this pull request Mar 27, 2024
…ctions (#683)

* Add socketTimeout to HttpClientConfiguration, and use that value downstream in CRTClientEngine in HTTPMonitoringOptions constructor. Update comments to clarify the preexisting connetTimeout config's usage. Fix URLSession client to use the new socketTimeout config for timeoutIntervalForRequest instead of connectTimeout.

* Bump CRT version to 0.29.0.

* Update comments & delete default value of 2 seconds from config initializers. Instead, use 0 (no socket timeout) if it was not provided by end-user in the config.

* Set connection timeout for URLSessionHTTPClient as well, using URLRequest:timeoutInterval config.

---------

Co-authored-by: Sichan Yoo <chanyoo@amazon.com>
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.

2 participants