【发布时间】:2022-09-29 23:52:47
【问题描述】:
这是我的 Polly 实现,它有两个策略,一个超时和一个重试。这个想法是当sql超时时,超时跨度会变长,所以sql server有更多的时间来做这项工作。
但是,当使用需要几分钟才能完成模拟超时的 sp 时,我没有看到超时策略触发了 3 次(附加调试器或仅搜索输出日志)。它触发一次,然后TimeoutRejectedException 将被抛出。
var timeoutPerTry = Policy
.TimeoutAsync(context =>
{
////enlarge timeout every time it happens
taskTimeoutInSeconds = (int)(timeoutMs / 1000);
Log.LogVerbose(
$\"log something\");
return TimeSpan.FromMilliseconds(timeoutMs);
}, TimeoutStrategy.Optimistic);
// retry SqlException up to MaxRetries
var retryPolicy = Policy
.Handle<SqlException>()
.RetryAsync(Constants.MaxRetries,
(response, calculatedWaitDuration, context) =>
{
Log.LogError(
$\"Failed dynamic execution attempt. Retrying. {response.Message} - {response.StackTrace}\");
});
try
{
////combine timeout policy and retry policy
var combinedPolicy = retryPolicy.WrapAsync(timeoutPerTry);
// ReSharper disable once AccessToDisposedClosure
var results =
await combinedPolicy.ExecuteAsync<IEnumerable<T>>(async () => {
var connectionString = ConnectionStringHelper.GetConnectionString(warehouseId);
using (var connection = new SqlConnection(connectionString)) // assumed no need for using block as closed by caller
{
await connection.OpenAsync();
using (var cmd = new SqlCommand
{
CommandType = commandType,
CommandTimeout = taskTimeoutInSeconds, // in secs
CommandText = \"JerrySimulateSlowSp\"
})
{
cmd.Parameters.AddRange(parameters.ToArray());
cmd.Connection = connection;
using (var reader = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection))
{
return mapper.Map<IDataReader, IEnumerable<T>>(reader);
}
}
}
});
return results;
//cmd.Connection = null;
}
catch (SqlException ex) when (ex.Number == -2) // -2 is a sql timeout
{
throw new ThunderTimeoutException(Constants.HttpResponseTimeoutSql);
}
catch (TimeoutRejectedException)
{
throw new ThunderTimeoutException(Constants.HttpResponseTimeoutTask);
}
标签: c# .net ado.net timeout polly