向Polly中的回退动作发送参数



我正在尝试执行一个请求,并返回一个响应与2个执行器,使用与回退策略的Polly库。下面是我到目前为止的代码:

private IExecuter primary;
private IExecuter secondary;
private readonly Policy _policy;
public Client()
{
primary = new Executer("primary");
secondary = new Executer("secondary");
_policy = Policy
.Handle<Exception>()
.Fallback((request) => GetResponseFallback(request));
}
public Response Process(Request request)
{
return _policy.Execute( GetResponse(request));
}
private Response GetResponse(Request request)
{
return this.primary.Execute(request);
}
private Response GetResponseFallback(Request request)
{
return secondary.Execute(request);
}

这段代码的问题是我不能在这行上放一个Request参数:.Fallback((request) => GetResponseFallback(request));

代码无法编译,因为错误:

"无法从'System.Threading '转换。CancellationToken'到'PollyPOC.Request'">

如何使代码编译并告诉回退策略动作将接收Request参数到GetResponseFallback动作?

为了将数据传递给Fallback方法,你需要利用上下文

为了简单起见,让我稍微简化一下您的实现,向您展示如何使用Context:

private int GetResponse(int request)
{
return request + 1;
}
private int GetResponseFallback(int request)
{
return request + 2;
}

所以我只是去掉了IExecuter,RequestResponse的概念,以保持示例代码尽可能简单。


要将数据传递给GetResponseFallback,我们需要像这样更改参数:

private const string requestKey = "request"; 
private int GetResponseFallback(Context ctx)
{
var request = (int)ctx[requestKey];
return request + 2;
}

因此,我们已经从Context中检索了request数据。现在我们需要以某种方式将该信息传递给GetResponseFallback调用。

好的是我们不需要修改GetResponse。另一方面,我们需要像这样调整Process方法:

private int Process(int request)
{
var contextData = new Dictionary<string, object> { { requestKey, request } };
_policy = Policy<int>
.Handle<Exception>()
.Fallback((ctx) => GetResponseFallback(ctx), (_, __) => { });
return _policy.Execute((_) => GetResponse(request), contextData);
}
  • 我们已经创建了一个contextData字典来存储输入参数
  • 我们使用了一个特殊的Fallback重载,我们必须定义两个委托:
    • 不幸的是,没有过载,我们只需要提供一个Action<Context> fallbackAction参数
public static FallbackPolicy Fallback(this PolicyBuilder policyBuilder, Action<Context> fallbackAction, Action<Exception, Context> onFallback)
  • 因为我们不想在onFallback里面做任何事情所以我这样定义了(_,__) => { }
  • 我们调用了一个特殊的Execute重载,语法如下:
public void Execute(Action<Context> action, IDictionary<string, object> contextData)
  • 因为我们没有直接将Context参数传递给GetResponse所以我们可以在这里使用丢弃运算符(_) => GetResponse(...)

最后一件重要的事情:我必须将_policy变量类型更改为Policy<int>以指示返回类型。


为了完整起见,这里是完整的源代码:

private static Policy<int> _policy;
static void Main(string[] args)
{
Console.WriteLine(Process(1));
}
private const string requestKey = "request";
static int Process(int request)
{
var contextData = new Dictionary<string, object> { { requestKey, request } };
_policy = Policy<int>
.Handle<Exception>()
.Fallback((ctx) => GetResponseFallback(ctx), (_, __) => { });
return _policy.Execute((_) => GetResponse(request), contextData);
}
static int GetResponse(int request)
{
throw new Exception();
return request + 1;
}
static int GetResponseFallback(Context ctx)
{
var request = (int)ctx[requestKey];
return request + 2;
}

相关内容

  • 没有找到相关文章

最新更新