【发布时间】:2020-06-19 15:36:36
【问题描述】:
所以,我正在编写一些使用 Polly 获取锁的重试逻辑。整体超时值将由 API 调用者提供。我知道我可以在整体超时中包装策略。但是,如果提供的超时值太低,是否有办法确保策略至少执行一次?
显然我可以在执行策略之前单独调用委托,但我只是想知道是否有办法在 Polly 中表达此要求。
var result = Policy.Timeout(timeoutFromApiCaller)
.Wrap(Policy.HandleResult(false)
.WaitAndRetryForever(_ => TimeSpan.FromMilliseconds(500))
.Execute(() => this.TryEnterLock());
如果 timeoutFromApiCaller 是 1 tick 并且很有可能需要更长的时间才能达到超时策略,则不会调用委托(该策略将超时并抛出 TimeoutRejectedException)。
我希望发生的事情可以表达为:
var result = this.TryEnterLock();
if (!result)
{
result = Policy.Timeout(timeoutFromApiCaller)
.Wrap(Policy.HandleResult(false)
.WaitAndRetryForever(_ => TimeSpan.FromMilliseconds(500))
.Execute(() => this.TryEnterLock());
}
不过要是能用纯波利来表达就好了……
【问题讨论】:
-
请分享你的代码
-
当前您的实现没有全局(整体)超时。它作为“本地”运行。假设超时为 2 秒,重试次数为 3,重试延迟为 4 秒。它等待 2 秒,然后在下一次重试之前暂停 4 秒……重要的是您包装策略的顺序:如果内部失败,则升级到外部。本地超时:重试 > 超时,全局超时:超时 > 重试,本地+整体:超时 > 重试 > 超时。
-
谢谢@PeterCsala,你知道我想要实现的目标是否可行吗?即总是尝试一次然后遵守任何 global 超时?
-
@Nick 事实上,开箱即用,您至少获得了一次通话保证。因为重试计数 3 意味着 4 次尝试。初始调用是第一次尝试。如果失败,则将触发重试。因此,您的第一次重试将是您的第二次尝试。
-
@PeterCsala,我稍微修改了代码,因此它实际上代表了我想要实现的目标。 IE。我在外部范围内超时并在内部范围内重试。如果在内部有机会操作之前外部超时,这将抛出
TimeoutRejectedException。我还指出了我希望它如何运作。