根据重试次数调整超时时间
Adjusting Timeout duration based on Retry Count
我想使用 Polly 执行以下操作:尝试一个超时时间很短的请求。如果失败,请使用更长的超时重试。
我看到 Retry
可以像这样访问 retryCount
:
Policy
.Handle<SomeExceptionType>()
.Retry(3, (exception, retryCount, context) =>
{
// do something
});
我看到 Timeout
可以指定 int
或 TimeSpan
,像这样:
Policy.Timeout(TimeSpan.FromMilliseconds(2500))
我什至看到你可以将一个函数传递给超时,就像这样:
Policy.Timeout(() => myTimeoutProvider)) // Func<TimeSpan> myTimeoutProvider
Func
选项似乎是最有希望的,但它在哪里可以访问重试计数?将状态保持在策略之外很诱人,但如果我想以线程安全的方式共享策略,那将很危险。
有什么建议吗?
发件人:https://github.com/App-vNext/Polly/wiki/Timeout
int retryCount_ = 0;
Func<TimeSpan> myTimeoutProvider = () =>
TimeSpan.FromMilliseconds(25*retryCount_);
// Configure variable timeout via a func provider.
Policy
.Timeout(() => myTimeoutProvider)) // Func<TimeSpan> myTimeoutProvider
.Retry(3, (exception, retryCount, context) =>
{
retryCount_ = retryCount;
// do something
})
或设置超时类似于以下所示的方式:
Policy
.Handle<SomeExceptionType>()
.WaitAndRetry(5, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
);
更新
您还可以连接到 onTimeoutAsync
回调并不断增加 myTimeoutProvider
所依赖的局部变量。
您可以使用 Polly Context
在执行中涉及的不同策略之间传递状态数据。 Polly Context
的唯一实例随每次 Polly 执行而流动,因此这完全是 thread-safe.
有关此技术的更多详细信息 in this blog post。
例如:
const string RetryCountKey = "RetryCount";
RetryPolicy retryStoringRetryCount = Policy
.Handle<Exception>()
.Retry(3, (exception, retryCount, context) =>
{
Console.WriteLine("Storing retry count of " + retryCount + " in execution context.");
context[RetryCountKey] = retryCount;
});
TimeoutPolicy timeoutBasedOnRetryCount = Policy
.Timeout(context =>
{
int tryCount;
try
{
tryCount = (int) context[RetryCountKey];
}
catch
{
tryCount = 0; // choose your own default for when it is not set; also applies to first try, before any retries
}
int timeoutMs = 25 * (tryCount + 1);
Console.WriteLine("Obtained retry count of " + tryCount + " from context, thus timeout is " + timeoutMs + " ms.");
return TimeSpan.FromMilliseconds(timeoutMs);
});
PolicyWrap policiesTogether = retryStoringRetryCount.Wrap(timeoutBasedOnRetryCount);
(注:当然这个^可以写得更简洁。在这里列出是为了最大程度的清楚。)
我想使用 Polly 执行以下操作:尝试一个超时时间很短的请求。如果失败,请使用更长的超时重试。
我看到 Retry
可以像这样访问 retryCount
:
Policy
.Handle<SomeExceptionType>()
.Retry(3, (exception, retryCount, context) =>
{
// do something
});
我看到 Timeout
可以指定 int
或 TimeSpan
,像这样:
Policy.Timeout(TimeSpan.FromMilliseconds(2500))
我什至看到你可以将一个函数传递给超时,就像这样:
Policy.Timeout(() => myTimeoutProvider)) // Func<TimeSpan> myTimeoutProvider
Func
选项似乎是最有希望的,但它在哪里可以访问重试计数?将状态保持在策略之外很诱人,但如果我想以线程安全的方式共享策略,那将很危险。
有什么建议吗?
发件人:https://github.com/App-vNext/Polly/wiki/Timeout
int retryCount_ = 0;
Func<TimeSpan> myTimeoutProvider = () =>
TimeSpan.FromMilliseconds(25*retryCount_);
// Configure variable timeout via a func provider.
Policy
.Timeout(() => myTimeoutProvider)) // Func<TimeSpan> myTimeoutProvider
.Retry(3, (exception, retryCount, context) =>
{
retryCount_ = retryCount;
// do something
})
或设置超时类似于以下所示的方式:
Policy
.Handle<SomeExceptionType>()
.WaitAndRetry(5, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
);
更新
您还可以连接到 onTimeoutAsync
回调并不断增加 myTimeoutProvider
所依赖的局部变量。
您可以使用 Polly Context
在执行中涉及的不同策略之间传递状态数据。 Polly Context
的唯一实例随每次 Polly 执行而流动,因此这完全是 thread-safe.
有关此技术的更多详细信息 in this blog post。
例如:
const string RetryCountKey = "RetryCount";
RetryPolicy retryStoringRetryCount = Policy
.Handle<Exception>()
.Retry(3, (exception, retryCount, context) =>
{
Console.WriteLine("Storing retry count of " + retryCount + " in execution context.");
context[RetryCountKey] = retryCount;
});
TimeoutPolicy timeoutBasedOnRetryCount = Policy
.Timeout(context =>
{
int tryCount;
try
{
tryCount = (int) context[RetryCountKey];
}
catch
{
tryCount = 0; // choose your own default for when it is not set; also applies to first try, before any retries
}
int timeoutMs = 25 * (tryCount + 1);
Console.WriteLine("Obtained retry count of " + tryCount + " from context, thus timeout is " + timeoutMs + " ms.");
return TimeSpan.FromMilliseconds(timeoutMs);
});
PolicyWrap policiesTogether = retryStoringRetryCount.Wrap(timeoutBasedOnRetryCount);
(注:当然这个^可以写得更简洁。在这里列出是为了最大程度的清楚。)