我正在使用断路器策略进行数据库访问。我有一个多租户结构,其中包含用于存储不同客户端数据的相同数据库。我的申请可能会触及任何租户。如果一个数据库关闭,其他数据库则可能没有关闭。如果我打开断路器,我只想为那个租户打开它。
我为每个租户创建了相同的策略,并将它们存储在以租户名称为键的Dictionary中。进行数据库调用时,我从字典中检索匹配的策略并执行它。
我相当确定这是可行的,但是我想知道它是否太复杂了。也许波莉已经以此作为一种方式。有没有办法将策略行为绑定到租户的数据值?
有什么建议吗?
答案 0 :(得分:0)
问题中所述的设计符合以下要求:对要视为具有不同健康状况的下游系统,维护单独的断路器策略 instance 。
Polly不提供断路器,该断路器每个键都维护着很大的内部健康状态字典。
Polly确实提供了PolicyRegistry
;从根本上讲,这是一个类似于问题中所述的密钥策略字典。
如果需要在PolicyWrap中使用断路器策略,并且该策略是PolicyWrap中唯一需要改变每个租户的内容,则可以使用'policy selector' within the PolicyWrap来选择或制作适当的策略在运行时。
上面链接中的示例代码:
public class AsyncPolicySelector<TResult> : AsyncPolicy<TResult>
{
private readonly Func<Context, IAsyncPolicy<TResult>> policySelector;
public static AsyncPolicySelector<TResult> Create(Func<Context, IAsyncPolicy<TResult>> policySelector)
{
return new AsyncPolicySelector<TResult>(policySelector);
}
private AsyncPolicySelector(Func<Context, IAsyncPolicy<TResult>> policySelector)
{
this.policySelector = policySelector;
}
protected override Task<TResult> ImplementationAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext)
{
return policySelector(context).ExecuteAsync(action, context, cancellationToken, continueOnCapturedContext);
}
}
使用AsyncPolicySelector<TResult>
为您创建自定义Func<Context, IAsyncPolicy<TResult>> policySelector
策略,该策略可以选择上一个策略或重新创建(需要时)策略。
Polly Context
has dictionary semantics,因此您可以在执行之前在Context
上设置租户ID。
Context context = new Context();
context["TenantId"] = /* tenant id from somewhere */
// (you must execute through the PolicyWrap then with an overload passing in this context)
并使用Func<Context, IAsyncPolicy<TResult>> policySelector
通过context["TenantId"]
从您的字典或PolicyRegistry
中检索断路器;或为该租户制造一个新的断路器(如果还没有)。