首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在Polly策略回退中将Polly策略与访问已处理异常结合起来

在Polly策略回退中将Polly策略与访问已处理异常结合起来
EN

Stack Overflow用户
提问于 2022-07-18 00:49:39
回答 1查看 175关注 0票数 1

给出以下F#片段

代码语言:javascript
代码运行次数:0
运行
复制
//User Code
.. code that can throw exceptions
"Success"

P1政策

代码语言:javascript
代码运行次数:0
运行
复制
Policy
    .Handle<CosmosException>(fun cx -> cx.StatusCode = HttpStatusCode.TooManyRequests)
    .WaitAndRetryForever((fun _ cx _ -> (cx :?> CosmosException).RetryAfter.Value), (fun _ _ _ _ -> ()))

P2政策

代码语言:javascript
代码运行次数:0
运行
复制
Policy<string>
    .Handle<Exception>()
    .Fallback("Failure")

P3策略

代码语言:javascript
代码运行次数:0
运行
复制
Policy<string>
    .Handle<Exception>()
    .Fallback(fun ex -> ex.Message)

问题1-如何将P1和P2结合起来?

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

  • 如果用户代码成功,“成功”将返回给调用方。
  • 如果用户代码抛出CosmosException,则P将永远使用返回的RetryAfter TimeSpan重试
  • 如果用户代码引发任何其他异常,则"Failure“将返回给调用方

问题2-如何编写P3?

在构造回退值时,似乎没有允许访问已处理异常来使用该异常的回退重载。

最后一个范围是将P1和P3组合起来,以获得一个策略PFinal,以便:

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

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-18 13:33:04

对问题1的答复

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

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

代码语言:javascript
代码运行次数:0
运行
复制
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);
  • 请注意,我们必须将Policy更改为Policy<string> in p1
  • 还请注意,sleepDurationProvider将不会将Exception作为参数接收。
    • 相反,它将接收一个DelegateResult,它具有两个互斥属性:ExceptionResult

对问题2的答复

  • 存在重载,其中fallbackAction委托接收作为参数的DelegateResult<string>
代码语言:javascript
代码运行次数:0
运行
复制
var p2 = Policy<string>
    .Handle<Exception>()
    .Fallback(fallbackAction: (dr, _, __) => dr.Exception.Message,
              onFallback: (_, __) => { });

更新#1:提供清晰性

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

变更前:

代码语言:javascript
代码运行次数:0
运行
复制
//user code

//to be decorated code which might throw exception

return "Success";

变更后:

代码语言:javascript
代码运行次数:0
运行
复制
//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),因为最右的参数是最内部的参数,最左边的参数是最外层的参数。所以,在你的例子中,重试是内在的,而后退是外部的。

抱歉给您带来不便。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73016363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档