The design stated in the question is correct for the requirement: maintain a separate circuit-breaker policy instance per downstream system you want to treat as having distinct health status.
Polly does not offer a circuit-breaker which maintains a big internal dictionary of health states per some key.
Polly does offer a PolicyRegistry
; this is fundamentally a key-policy dictionary similar to described in the question.
If the circuit-breaker Policy is required to be used mid-PolicyWrap, and is the only thing in the PolicyWrap that needs to vary per-tenant, you can use a 'policy selector' within the PolicyWrap to select or manufacture an appropriate policy at runtime.
The example code in the link above:
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);
}
}
creates you a custom AsyncPolicySelector<TResult>
policy using a Func<Context, IAsyncPolicy<TResult>> policySelector
which can select-a-previous or manufacture afresh (when needed) a policy.
Polly Context
has dictionary semantics so you could set the tenant-id on Context
prior to execution.
Context context = new Context();
context["TenantId"] = /* tenant id from somewhere */
// (you must execute through the PolicyWrap then with an overload passing in this context)
And use a Func<Context, IAsyncPolicy<TResult>> policySelector
to retrieve the circuit-breaker by context["TenantId"]
from your dictionary or PolicyRegistry
; or manufacture a new circuit-breaker for that tenant if there was not already one.