我的策略行为可以根据执行中的数据进行更改吗?

时间:2019-03-01 00:20:08

标签: circuit-breaker polly

我正在使用断路器策略进行数据库访问。我有一个多租户结构,其中包含用于存储不同客户端数据的相同数据库。我的申请可能会触及任何租户。如果一个数据库关闭,其他数据库则可能没有关闭。如果我打开断路器,我只想为那个租户打开它。

我为每个租户创建了相同的策略,并将它们存储在以租户名称为键的Dictionary中。进行数据库调用时,我从字典中检索匹配的策略并执行它。

我相当确定这是可行的,但是我想知道它是否太复杂了。也许波莉已经以此作为一种方式。有没有办法将策略行为绑定到租户的数据值?

有什么建议吗?

1 个答案:

答案 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中检索断路器;或为该租户制造一个新的断路器(如果还没有)。