下面的第一个示例将重试之间的总等待时间限制为总时间跨度myWaitLimit
,但不考虑在返回之前对 CosmosDB 的调用花费了多长时间DocumentClientException
。因为 PollyContext
是执行范围的,所以这是线程安全的。就像是:
policy = Policy.Handle<DocumentClientException>(ex => ex.StatusCode == (HttpStatusCode)429)
.WaitAndRetryAsync(
retryCount: retries,
sleepDurationProvider: (retryCount, exception, context) => {
DocumentClientException dce = exception as DocumentClientException;
TimeSpan toWait = dce.RetryAfter;
TimeSpan waitedSoFar;
if (!Context.TryGetValue("WaitedSoFar", out waitedSoFar)) waitedSoFar = TimeSpan.Zero; // (probably some extra casting actually needed between object and TimeSpan, but this kind of idea ...)
waitedSoFar = waitedSoFar + toWait;
if (waitedSoFar > myWaitLimit)
throw dce; // or use ExceptionDispatchInfo to preserve stack trace
Context["WaitedSoFar"] = waitedSoFar; // (magic string "WaitedSoFar" only for readability; of course you can factor this out)
return toWait;
},
onRetryAsync: async (res, timespan, retryCount, context) => {
});
另一种方法可以使用 timeout 来限制整体执行时间(发生 429 秒时)CancellationToken
。在发出信号后,以下方法将不再重试CancellationToken
。sleepDurationProvider
这种方法被建模为接近问题中请求的功能,但超时显然只有在返回 429 响应并调用委托时才会生效。
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(/* my timeout */);
var policy = Policy.Handle<DocumentClientException>(ex => ex.StatusCode == (HttpStatusCode)429)
.WaitAndRetryAsync(
retryCount: retries,
sleepDurationProvider: (retryCount, exception, context) => {
if (cts.IsCancellationRequested) throw exception; // or use ExceptionDispatchInfo to preserve stack trace
DocumentClientException dce = exception as DocumentClientException;
return dce.RetryAfter;
},
onRetryAsync: async (res, timespan, retryCount, context) => {
});
如果您不想policy
在与使用它相同的范围内定义并关闭变量(如上面的示例所做的那样),您可以使用 Pollycts
进行传递,如本博文中所述。CancellationTokenSource
Context
或者,Polly 提供了一个TimeoutPolicy
. 使用PolicyWrap
您可以将其包装在重试策略之外。然后可以对整体执行施加超时,无论是否发生 429。
如果该策略旨在管理本质上不采用 a 的 Cosmos DB 异步调用,则如果您想在该时间间隔强制CancellationToken
超时,则需要使用该策略。但是,请注意 wiki 的操作方式:它允许调用线程离开不可取消的调用,但不会单方面取消不可取消的调用。该调用可能稍后会出错,或者继续完成。 TimeoutStrategy.Pessimistic
TimeoutStrategy.Pessimistic
显然,请根据您的上下文考虑上述选项中的最佳选择。