将参数发送到 Polly 中的回退 Action
Send parameters to fallback Action in Polly
我正在尝试使用具有回退策略的 Polly 库来执行一个请求和 return 一个响应,有 2 个执行者。到目前为止,这是我的代码:
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);
}
此代码的问题是我无法在此行中放置请求参数:
.Fallback((request) => GetResponseFallback(request));
代码无法编译,因为错误:
"cannot convert from 'System.Threading.CancellationToken' to 'PollyPOC.Request'"
如何编译代码并告知回退策略该操作将接收 GetResponseFallback
操作的 Request
参数?
为了将数据传递给您的后备方法,您需要利用 Context
为了简单起见,让我稍微简化一下您的实现,向您展示如何使用 Context
:
private int GetResponse(int request)
{
return request + 1;
}
private int GetResponseFallback(int request)
{
return request + 2;
}
所以我去掉了 IExecuter
、Request
和 Response
概念,使示例代码尽可能简单。
要将数据传递给您的 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
字典来存储输入参数
- 我们使用了 special overload of the Fallback,我们必须在其中定义两个委托:
- 不幸的是没有重载,我们只需要提供一个
Action<Context> fallbackAction
参数
public static FallbackPolicy Fallback(this PolicyBuilder policyBuilder, Action<Context> fallbackAction, Action<Exception, Context> onFallback)
- 因为我们不想在
onFallback
中做任何事情,所以我这样定义 (_,__) => { }
- 我们调用了一个special overload of Execute,语法如下:
public void Execute(Action<Context> action, IDictionary<string, object> contextData)
- 因为我们没有直接将 Context 参数传递给
GetResponse
这就是为什么我们可以在这里使用 discard operator (_) => GetResponse(...)
最后一件重要的事情:我必须将 _policy
变量类型更改为 Policy<int>
以指示 return 类型。
为了完整起见,这里是完整的源代码:
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;
}
我正在尝试使用具有回退策略的 Polly 库来执行一个请求和 return 一个响应,有 2 个执行者。到目前为止,这是我的代码:
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);
}
此代码的问题是我无法在此行中放置请求参数:
.Fallback((request) => GetResponseFallback(request));
代码无法编译,因为错误:
"cannot convert from 'System.Threading.CancellationToken' to 'PollyPOC.Request'"
如何编译代码并告知回退策略该操作将接收 GetResponseFallback
操作的 Request
参数?
为了将数据传递给您的后备方法,您需要利用 Context
为了简单起见,让我稍微简化一下您的实现,向您展示如何使用 Context
:
private int GetResponse(int request)
{
return request + 1;
}
private int GetResponseFallback(int request)
{
return request + 2;
}
所以我去掉了 IExecuter
、Request
和 Response
概念,使示例代码尽可能简单。
要将数据传递给您的 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
字典来存储输入参数 - 我们使用了 special overload of the Fallback,我们必须在其中定义两个委托:
- 不幸的是没有重载,我们只需要提供一个
Action<Context> fallbackAction
参数
- 不幸的是没有重载,我们只需要提供一个
public static FallbackPolicy Fallback(this PolicyBuilder policyBuilder, Action<Context> fallbackAction, Action<Exception, Context> onFallback)
- 因为我们不想在
onFallback
中做任何事情,所以我这样定义(_,__) => { }
- 我们调用了一个special overload of Execute,语法如下:
public void Execute(Action<Context> action, IDictionary<string, object> contextData)
- 因为我们没有直接将 Context 参数传递给
GetResponse
这就是为什么我们可以在这里使用 discard operator(_) => GetResponse(...)
最后一件重要的事情:我必须将 _policy
变量类型更改为 Policy<int>
以指示 return 类型。
为了完整起见,这里是完整的源代码:
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;
}