【问题标题】:Combining Polly policies and accessing handled exception in Polly policy Fallback在 Polly 策略 Fallback 中组合 Polly 策略并访问已处理的异常
【发布时间】:2022-10-02 05:43:34
【问题描述】:

给定以下 F# sn-ps

//User Code
.. code that can throw exceptions
\"Success\"

P1 政策

Policy
    .Handle<CosmosException>(fun cx -> cx.StatusCode = HttpStatusCode.TooManyRequests)
    .WaitAndRetryForever((fun _ cx _ -> (cx :?> CosmosException).RetryAfter.Value), (fun _ _ _ _ -> ()))

P2 政策

Policy<string>
    .Handle<Exception>()
    .Fallback(\"Failure\")

P3 政策

Policy<string>
    .Handle<Exception>()
    .Fallback(fun ex -> ex.Message)

问题 #1 - 如何组合 P1 和 P2?

将 P1 和 P2 组合到策略 P 中,以便:

  • 如果用户代码成功,“成功”返回给调用者
  • 如果用户代码抛出 CosmosException,P 使用返回的 RetryAfter TimeSpan 永远重试
  • 如果用户代码抛出任何其他异常,“失败”将返回给调用者

问题 #2 - 如何写 P3?

在构造回退返回值时,似乎没有允许访问处理的异常以使用它的回退重载

最终范围是组合 P1 和 P3 以获得策略 PFinal,这样:

  • 如果用户代码成功,“成功”返回给调用者
  • 如果用户代码抛出 CosmosException,PFinal 使用返回的 RetryAfter TimeSpan 永远重试
  • 如果用户代码抛出任何其他异常,则将处理的异常消息返回给调用者

    标签: f# fallback polly retry-logic


    【解决方案1】:

    回答问题 1

    为了能够链接策略,您需要将它们定义为兼容策略。你的 p2 返回一个 string 而你的 p1 什么也不返回。因此,您还需要更改 p1 以返回 string。然后您可以使用Policy.Wrap 定义链接,escalation

    我不是 F# 开发人员,所以我将在 C# 中介绍解决方案。但是这两种语言的想法是相同的:

    var p1 = Policy<string>
        .Handle<CosmosException>(ex => ex.StatusCode == HttpStatusCode.TooManyRequests)
        .WaitAndRetryForever(sleepDurationProvider: (_, dr, __) => ((CosmosException)dr.Exception).RetryAfter.Value,
                            onRetry: (_, __, ___) => { });
    var p2 = Policy<string>
        .Handle<Exception>()
        .Fallback("Failure");
    
    var p = Policy.Wrap(p1, p2);
    
    • 请注意,我们必须将p1 中的Policy 更改为Policy&lt;string&gt;
    • 还要注意sleepDurationProvider 不会接收Exception 作为参数

    回答问题 2

    • 存在重载,fallbackAction 委托接收 DelegateResult&lt;string&gt; 作为参数
    var p2 = Policy<string>
        .Handle<Exception>()
        .Fallback(fallbackAction: (dr, _, __) => dr.Exception.Message,
                  onFallback: (_, __) => { });
    

    更新#1: 提供清晰

    p1 定义从Policy 更改为Policy&lt;string&gt; 还有另一个含义:您要修饰的代码应该返回一个字符串(即“成功”)

    变更前:

    //user code
    
    //to be decorated code which might throw exception
    
    return "Success";
    

    更改后:

    //user code
    
    //The decorated code either return "Success" or throws CosmosException 
    return combinedPolicy.Execute(...
    

    更新#2: 修复排序

    我建议将p1p2Policy.Wrap 链接起来。不幸的是,我向您展示了错误的顺序Policy.Wrap(p1, p2)。这正确一个Policy.Wrap(p2, p1),因为最右边的参数是最内部的,最左边的参数是最外部的。因此,在您的情况下,重试是内部的,而后备是外部的。

    给您带来的不便深表歉意。

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      • 2022-10-19
      相关资源
      最近更新 更多