【问题标题】:Understanding the semantics of Polly policies when separating policy definition from execution将策略定义与执行分离时了解 Polly 策略的语义
【发布时间】:2017-06-10 05:55:36
【问题描述】:

对于Polly,我希望在两个不同的语句中定义我的策略和执行该策略,如下所示:

// Policy definition
var policy = Policy
   .HandleResult<IRestResponse>(predicate)
   .Retry(2);

// Policy execution
policy.ExecuteAndCapture(() =>
{
    DoSomethingAndReturnAnIRestResponse();
};

我想这样做,以便更好地重用我的重试策略,例如用于依赖注入。

我试图了解在以这种方式拆分策略和执行时是否有任何考虑因素,例如,如果有任何“状态”(因为没有更好的术语)可能不会包含在 policy 中从策略定义到执行的对象。

沿着这些思路,我注意到当我以上述方式使用 Polly 的 ExecuteAndCapture() 时,某些属性(与捕获最终异常/结果相关的,与 ExecuteAndCapture() 相关联的属性)没有显示在 @987654332 上@ 目的。根据文档(herehere),在完成以下策略后:

var policy = Policy
   .HandleResult<IRestResponse>(predicate)
   .Retry(2)
   .ExecuteAndCapture(() =>
    {
       DoSomethingAndReturnAnIRestResponse();
    });

...你应该回来了:

PolicyResult.Outcome
PolicyResult.FinalException
PolicyResult.ExceptionType
PolicyResult.Result

这确实发生了,然后ExecuteAndCapture() 与策略定义在同一语句中。但是,当将策略定义与执行分开时,这些属性不可用。我天真地以为它们会出现在现有的 policy 对象上,但它们不会:

看来我需要创建一个新的变量赋值才能访问这些属性:

这里有什么问题吗?

【问题讨论】:

    标签: c# .net polly


    【解决方案1】:

    不用担心。将策略与使用分开配置,并将它们注入使用站点,这是我们在生产中广泛使用的常见模式。

    所有 Polly 策略都是线程安全的,可以同时跨多个独立的调用站点使用。


    两种 Polly 策略线程安全地跨调用维护内部状态,以执行其设计的功能。如果您在调用站点之间共享这些策略实例,这会导致特定(预期)效果。

    CircuitBreaker / AdvancedCircuitBreaker

    存在理由是在通过策略发出的调用中根据成功/失败指标进行计数并采取行动。每个单独的策略实例都在内部为自己维护此状态。

    这样做的(预期的)功能结果是,如果您在多个呼叫站点共享一个CircuitBreakerPolicy 实例,那么这些多个呼叫站点将共享电路状态as discussed here

    • 当您希望这些呼叫站点共同中断时,跨呼叫站点共享相同的中断策略实例 - 例如,它们具有共同的下游依赖项。
    • 当您希望这些呼叫站点具有独立的电路状态并独立中断时,请勿跨呼叫站点共享断路器实例。

    Bulkhead

    存在的理由是限制通过它发出的调用的并发性。每个BulkheadPolicy 实例都在内部维护状态以跟踪它。

    这样做的(预期)功能结果是,当您在呼叫站点之间共享 BulkheadPolicy 实例时,这些呼叫站点会在它们之间共享舱壁容量。

    • 当您希望呼叫站点在它们之间共享隔板容量时,跨多个呼叫站点共享相同的BulkheadPolicy 实例。
    • 如果您希望多个呼叫站点具有独立的隔板容量,请不要在多个呼叫站点之间共享相同的 BulkheadPolicy 实例。

    没有其他类型的 Polly 策略在执行过程中维护策略实例中的内部状态。


    .ExecuteAndCapture(...)

    .ExecuteAndCapture(...) 调用的结果不在问题中的 任何一种 中的 policy 上。在这两种情况下(定义和执行在一个语句中;或分开),result of the .ExecuteAndCapture(...) call 是一个新的PolicyResult 实例。

    每次执行都会返回一个新的 PolicyResult 实例。 PolicyResult 永远不会作为状态存储在策略实例上(这会使策略不是线程安全的,并且不能跨调用站点重用)。

    在每个代码位置将var 更改为实际类型(PolicyPolicyResult),这样可能会更清楚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 2011-03-31
      相关资源
      最近更新 更多