Can I modify a Policy after it is built?
Can I modify a Policy after it is built?
I'm creating an API method call which takes a Policy as an argument.
However, in my method I'd like to 'add onto' this policy by including my own retry Action(s) so that I can perform intermediate logging and telemetry of my own. Similar in concept to adding Click events to a Windows UI control.
Is there a way to modify a Policy after it's created?
Or, is there a hook mechanism where I can define my own callbacks in the Execute method perhaps?
Thanks
-John
1 Answer
1
A Polly Policy is immutable; it cannot be modified after configuration. However, there are several ways in which you can attach extra behaviour to a policy.
Policy
There could be several approaches depending what you want to achieve.
Note: All examples in this answer refer to synchronous policies / policy-hooks used when executing delegates synchronously, but all the same behaviour exists for the async forms of policies.
Option 1: All policy types do offer delegate hooks such as onRetry; onBreak; onCacheHit, and similar. Extra behaviour (for example logging) can be added in these. The delegates attached to these hooks must be defined at policy configuration time. There are many examples in the Polly readme and Polly-Samples project. The Polly wiki covers all such delegate hooks in depth.
onRetry
onBreak
onCacheHit
Option 2: If the fact that these delegates (onRetry etc) must be defined at policy configuration time is a restriction: you can overcome this using Polly.Context. Most of the delegates such as onRetry exist in a form which takes Context as an input parameter. That Context is execution-scoped, can carry arbitrary data, and a Context instance can be passed in to the call to .Execute(...).
onRetry
Polly.Context
onRetry
Context
Context
Context
.Execute(...)
So you could define Context["ExtraAction"] = /* some Action */ and pass that in to .Execute(...). Then, the onRetry delegate could extract Action extraAction = Context["ExtraAction"] (with some defensive checks) and execute it extraAction(). This allows you to inject arbitrary behaviour to the onRetry delegate after the policy has been configured.
Context["ExtraAction"] = /* some Action */
.Execute(...)
onRetry
Action extraAction = Context["ExtraAction"]
extraAction()
onRetry
Option 3: Perform your extra logic in the delegate executed. Of course, you could write your own Execute(...) wrapper method which takes a delegate to execute, and a policy, but wraps in extra behaviour.
Execute(...)
public TResult MyExecute(ISyncPolicy policy, Func<TResult> toExecute)
{
return policy.Execute(() =>
{
/* do my extra stuff */
return toExecute();
}
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.