FallbackAsync 方法停止 REST 调用

问题描述

public static IAsyncPolicy<HttpResponseMessage> GetSaveExceptionPolicy(
            IServiceProvider serviceProvider)
{

    return Policy
        .HandleResult<HttpResponseMessage>(x => x.StatusCode == HttpStatusCode.Forbidden)
        .FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK),d =>
            {
                var mediator = serviceProvider.GetService<IMediatorService>();
                mediator.SaveFailedOnInvalidLock();
                return Task.CompletedTask;
            });
}
 serviceCollection
    .AddHttpClient<IMyClient,MyClient>(p =>
    {
        p.BaseAddress = baseAddress;
        p.Timeout = TimeSpan.FromMinutes(10);
        
    })
    .ConfigurePrimaryHttpMessageHandler(sp => new HttpClientHandler() { MaxConnectionsPerServer = 10})
    .AddPolicyHandler((serviceProvider,request) => GetSaveExceptionPolicy(serviceProvider));

这是调解员电话

public void SaveFailedOnInvalidLock()
{
    _logger.Error($"Data Point Saving failed");
    SaveFailedOnInvalidLock?.Invoke();
}

这个 MyClient Post 方法被非常频繁地调用。例如,在给定的一秒内,有 7 个调用正在进行。并且每一秒有 7 个继续。

应用程序正常工作,直到 Post 方法返回“HttpStatusCode.Forbidden”。 当它返回一个 Forbidden 时,接下来的一些调用不会到达 REST 端点。

这是因为某些连接不可用吗?例如:由于“禁止”状态和波利回退策略,很少有连接丢失? (因为最大限制是 10)?

或者这是由于 Async 及其时序导致第二批调用进入时连接仍在使用中?

提前致谢

解决方法

我能够通过在回退操作中返回相同的 http 响应消息(而不是创建新的 HTTPResponseMessage)来解决这个问题

我猜因为我有 MaxConnectionsPerServer = 10 并且我在给定时刻使用了其中的 7 个,如果我返回 new HttpResponseMessage(HttpStatusCode.OK) 有一些处理程序没有被处理或卡住。

这是我的新政策

public static AsyncFallbackPolicy<HttpResponseMessage> GetDataPointSaveExceptionPolicy(
    IServiceProvider serviceProvider)
{
   return Policy 
       .HandleResult<HttpResponseMessage>(x=>
           x.StatusCode ==  HttpStatusCode.Forbidden)
       .FallbackAsync(
           (res,cx,ct) =>
           {
               var dataServiceMediator = serviceProvider.GetService<IDataServiceMediatorService>();
               dataServiceMediator.DataPointSaveFailedOnInvalidLock();

               return Task.FromResult(res.Result); 
           },(ct,cx) => Task.CompletedTask);
}

这将返回 Task.FromResult(res.Result),并且没有处理问题,对 MyClient 的调用继续到达 REST 端点。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...