Skip to content

Keys and Context Data

Dylan Reisenberger edited this page Apr 2, 2018 · 11 revisions

Policy keys and context data are intended to provide supplementary information that can be used to track policy activity and events, in logging and metrics. (See the Roadmap for metrics proposals.)

Every single call through a Polly policy carries an instance of Context with it: this carries the values of the keys, for each call.

Available keys

PolicyWrapKey

Key type PolicyWrapKey
Description / Purpose A unique key for each PolicyWrap instance. While Context.PolicyKey varies with each policy instance used in a wrap, Context.PolicyWrapKey remains constant over the wrap.
Primary use Include in emitted events/stats/logging, to indicate PolicyWrap in use
Additional use (forthcoming) Retrieve a Policy Wrap from Registry?
Default if not set short-type-name+some-guid-part; null if execution not part of a PolicyWrap
Behaviour in PolicyWrap Retains own value. In a nested-wrap, takes value of outermost PolicyWrap in the wrap.
How specified? extension method .WithPolicyKey(string policyKey) on PolicyWrap; set-once-only enforced
How exposed? PolicyWrap.PolicyKey; exposed to execution as Context.PolicyWrapKey

PolicyKey

Key type Policy Key
Description / Purpose A unique key for an individual configured Policy instance
Primary use Include in emitted events/stats/logging, to indicate policy in use
Additional use (forthcoming) Retrieve a policy from registry
Default if not set short-type-name+some-guid-part
Behaviour in PolicyWrap Retains own value
How specified? extension method .WithPolicyKey(string policyKey) on Policy; set-once-only enforced
How exposed? Policy.PolicyKey; exposed to execution as Context.PolicyKey

ExecutionKey

Proposed to rename this OperationKey from v6.0. Perhaps a clearer representation of its function, and more clearly distinguished from ExecutionGuid. See #426. Other options: CallSiteKey or UsageKey.

Key type ExecutionKey
Description / Purpose A unique key for each call site usage of a policy. (A single policy instance may be re-used in multiple code locations (see wiki)).
Primary use Used by CachePolicy as the cache key for the given execution
Additional use Include in emitted events/stats/logging, to indicate where policy in use
Default if not set null
Behaviour in PolicyWrap Takes value passed by any preceding policy in the wrap
How specified? by passing a new Context(executionKey) with the Execute call
How exposed? Context.ExecutionKey

ExecutionGuid

Proposed to rename this CorrelationId from v6.0. See #426.

Key type ExecutionGuid
Description / Purpose A unique GUID for each invocation through a policy
Primary use Distinguish individual calls through the policy, so that stats-interpreting code can distinguish calls in multi-threaded environment
Additional use .
Default if not set Guid.NewGuid()
Behaviour in PolicyWrap Takes value passed by any preceding policy in the wrap
How specified? not for the user to specify - generated randomly by each call to Execute
How exposed? Context.ExecutionGuid

Usage

// Identify policies with a PolicyKey, using the WithPolicyKey() extension method
// (for example, for correlation in logs or metrics)

var policy = Policy
    .Handle<DataAccessException>()
    .Retry(3, onRetry: (exception, retryCount, context) =>
       {
           logger.Error($"Retry {retryCount} of {context.PolicyKey} at {context.ExecutionKey}, due to: {exception}.");
       })
    .WithPolicyKey("MyDataAccessPolicy");

// Identify call sites with an ExecutionKey, by passing in a Context
var customerDetails = policy.Execute(myDelegate, new Context("GetCustomerDetails"));

// "MyDataAccessPolicy" -> context.PolicyKey 
// "GetCustomerDetails  -> context.ExecutionKey


// Pass additional custom information from call site into execution context 
var policy = Policy
    .Handle<DataAccessException>()
    .Retry(3, onRetry: (exception, retryCount, context) =>
       {
           logger.Error($"Retry {retryCount} of {context.PolicyKey} at {context.ExecutionKey}, getting {context["Type"]} of id {context["Id"]}, due to: {exception}.  ExecutionGuid: {context.ExecutionGuid}");
       })
    .WithPolicyKey("MyDataAccessPolicy");

int id = ... // customer id from somewhere
var customerDetails = policy.Execute(() => GetCustomer(id), 
    new Context("GetCustomerDetails", new Dictionary<string, object>() {{"Type","Customer"},{"Id",id}}
    ));
Clone this wiki locally