-
Notifications
You must be signed in to change notification settings - Fork 23
Description
The default/configurable retry strategies do not seem to support retries on an IOException. However, the AWS SDK does consider an IOException to be transient under some conditions. I find that occasionally I receive an IOException caused by an underlying SocketException with error code 10054 (ConnectionReset), which means "an existing connection was forcibly closed by the remote host."
The AWS .NET SDK logic pertaining to retrying on IOException is (from RetryPolicy.cs):
// An IOException was thrown by the underlying http client.
// FileNotFoundException is not considered a transient error because
// we don't consider local .NET assembly file changes to be happening.
// If a FileNotFoundException happens there is most likey a bad install
// of the SDK or .NET assembly binding issue.
if (exception is IOException && exception is not FileNotFoundException)
{
#if !NETSTANDARD // ThreadAbortException is not NetStandard
// Don't retry IOExceptions that are caused by a ThreadAbortException
if (ExceptionUtils.IsInnerException<ThreadAbortException>(exception))
return false;
#endif
// Retry all other IOExceptions
return true;
}
else if (ExceptionUtils.IsInnerException<IOException>(exception))
{
return true;
} It would be very useful if this library would allow configuration of and provide a default for a retry policy for these transient exceptions.
The relevant excerpt of my stack trace is:
System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
--- End of inner exception stack trace ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
at System.Net.Http.HttpConnection.InitialFillAsync(Boolean async)
at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at EfficientDynamoDb.Internal.HttpApi.SendAsync(DynamoDbContextConfig config, HttpContent httpContent, CancellationToken cancellationToken)
at EfficientDynamoDb.DynamoDbContext.GetItemAsync[TEntity](DdbClassInfo classInfo, BuilderNode node, CancellationToken cancellationToken)
at EfficientDynamoDb.Operations.GetItem.GetItemEntityRequestBuilder`1.ToItemAsync(CancellationToken cancellationToken)