如何将Polly用于任意“故障”条件的重试和瞬态故障处理

时间:2018-08-05 23:57:35

标签: c# .net polly retrypolicy transient-failure

我要使用Polly而不是检查明显的“故障”,而是检查其他情况。具体来说,我想进行一个(异步)调用,例如httpClient.GetAsync(...),出于这个问题的目的,我知道该调用将会成功-即在执行以下命令之后:

var response = await _myHttpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(uri));

response.IsSuccessStatusCode将是true

让我们假设我遵循标准:

var content = await response.Content.ReadAsStringAsync();

content == { "Name":"Tom", "Age", 30", "ErrorCode":"12345" }

我希望我的策略逻辑根据响应的ErrorCode部分的内容(或不存在)进行执行。所以这只是我打的一个电话。

我该如何使用Polly?

1 个答案:

答案 0 :(得分:0)

您正在配置一个策略来保护HttpClient GetAsync方法,该方法返回Task<HttpResponseMessage>。您想使用异步处理程序将Policy<HttpResponseMessage>配置为使用此方法。

Policy<T>.HandleResult(Func<T, bool> filter)使您可以查看HttpResponseMessage并确定是否要处理该结果。

几个选择。第一,您可以在HandleResult方法中找出反序列化/读取HttpResponseMessage的json有效负载的方法。您只能使用Func<HttpResponseMessage, bool>。这需要同步发生,因为添加异步/等待会将返回类型更改为任务。

第二,您可以在更高级别上应用该策略。当您是httpclient.GetAsync(uri)时获取响应,然后反序列化内容。也许有一个Policy<HttpResponseMessage>包装了httpclient调用,并有一个Policy<MyAbstractApiResponse>在反序列化之后寻找自定义错误代码?

请注意,API错误实际上应该由HttpResponseMessage上的IsSuccessStatusCode属性拾取。您的REST api(是您的吗?这是一个假设)应该设置适合错误的状态代码,而不仅仅是200和自定义响应属性。

相关的进一步阅读:Check string content of response before retrying with Polly

更新:

class Consumer
{
  public void Test()
  {
    var apiResponse = Policy<IApiResponse>
      .HandleResult(resp => !string.IsNullOrWhiteSpace(resp.ErrorCode))
      // Setup Policy
      .ExecuteAsync(() => otherClassInstance.MakeApiCall());
  }
}

class OtherClass
{
  HttpClient httpClient = ...;
  public async Task<IApiResponse> MakeApiCall()
  {
    var response = Policy<HttpResponseMessage>
      .HandleResult(message => !message.IsSuccessStatusCode)
      // Setup Policy
      .ExecuteAsync(() => httpClient.GetAsync(url));

    var content = await response.ReadAsStringAsync();
    return new ApiResponse(content);
  }
}

在将它们组合在一起时,我并没有查看真正的方法名称或语法,因此可能无法编译。希望您能理解我要传达的想法,从另一个内部调用一项策略。