diff --git a/src/Polly/AsyncPolicy.ContextAndKeys.cs b/src/Polly/AsyncPolicy.ContextAndKeys.cs index cfe96d7a001..09fe154bc7b 100644 --- a/src/Polly/AsyncPolicy.ContextAndKeys.cs +++ b/src/Polly/AsyncPolicy.ContextAndKeys.cs @@ -9,7 +9,7 @@ public abstract partial class AsyncPolicy /// The unique, used-definable key to assign to this instance. public AsyncPolicy WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; @@ -22,7 +22,7 @@ public AsyncPolicy WithPolicyKey(string policyKey) /// The unique, used-definable key to assign to this instance. IAsyncPolicy IAsyncPolicy.WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; @@ -38,7 +38,7 @@ public abstract partial class AsyncPolicy /// The unique, used-definable key to assign to this instance. public AsyncPolicy WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; @@ -51,7 +51,7 @@ public AsyncPolicy WithPolicyKey(string policyKey) /// The unique, used-definable key to assign to this instance. IAsyncPolicy IAsyncPolicy.WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; diff --git a/src/Polly/AsyncPolicy.ExecuteOverloads.cs b/src/Polly/AsyncPolicy.ExecuteOverloads.cs index 25a781426fc..667b1d4cb4b 100644 --- a/src/Polly/AsyncPolicy.ExecuteOverloads.cs +++ b/src/Polly/AsyncPolicy.ExecuteOverloads.cs @@ -103,7 +103,7 @@ public async Task ExecuteAsync(Func action, Co } finally { - RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); + PolicyBase.RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); } } @@ -223,7 +223,7 @@ public async Task ExecuteAsync(Func ExecuteAsync(FuncThe unique, used-definable key to assign to this instance. public Policy WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; @@ -22,7 +22,7 @@ public Policy WithPolicyKey(string policyKey) /// The unique, used-definable key to assign to this instance. ISyncPolicy ISyncPolicy.WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; @@ -38,7 +38,7 @@ public abstract partial class Policy /// The unique, used-definable key to assign to this instance. public Policy WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; @@ -51,7 +51,7 @@ public Policy WithPolicyKey(string policyKey) /// The unique, used-definable key to assign to this instance. ISyncPolicy ISyncPolicy.WithPolicyKey(string policyKey) { - if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException; + if (policyKeyInternal != null) throw PolicyKeyMustBeImmutableException(nameof(policyKey)); policyKeyInternal = policyKey; return this; diff --git a/src/Polly/Policy.ExecuteOverloads.cs b/src/Polly/Policy.ExecuteOverloads.cs index 983bd75c9e4..4d7e2e666aa 100644 --- a/src/Polly/Policy.ExecuteOverloads.cs +++ b/src/Polly/Policy.ExecuteOverloads.cs @@ -69,7 +69,7 @@ public void Execute(Action action, Context context, } finally { - RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); + PolicyBase.RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); } } @@ -160,7 +160,7 @@ public TResult Execute(Func action } finally { - RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); + PolicyBase.RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); } } diff --git a/src/Polly/Policy.TResult.ExecuteOverloads.cs b/src/Polly/Policy.TResult.ExecuteOverloads.cs index 7d1b631923e..a6f13261aa0 100644 --- a/src/Polly/Policy.TResult.ExecuteOverloads.cs +++ b/src/Polly/Policy.TResult.ExecuteOverloads.cs @@ -83,7 +83,7 @@ public TResult Execute(Func action, Context } finally { - RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); + PolicyBase.RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey); } } diff --git a/src/Polly/PolicyBase.ContextAndKeys.cs b/src/Polly/PolicyBase.ContextAndKeys.cs index cbcf0865d77..8827cb266d8 100644 --- a/src/Polly/PolicyBase.ContextAndKeys.cs +++ b/src/Polly/PolicyBase.ContextAndKeys.cs @@ -12,7 +12,19 @@ public abstract partial class PolicyBase /// public string PolicyKey => policyKeyInternal ?? (policyKeyInternal = GetType().Name + "-" + KeyHelper.GuidPart()); - internal static ArgumentException PolicyKeyMustBeImmutableException => new("PolicyKey cannot be changed once set; or (when using the default value after the PolicyKey property has been accessed.", "policyKey"); + internal static ArgumentException PolicyKeyMustBeImmutableException(string policyKeyParamName) => new ("PolicyKey cannot be changed once set; or (when using the default value after the PolicyKey property has been accessed.", policyKeyParamName); + + /// + /// Restores the supplied keys to the execution . + /// + /// The execution . + /// The prior to execution through this policy. + /// The prior to execution through this policy. + internal static void RestorePolicyContext(Context executionContext, string priorPolicyWrapKey, string priorPolicyKey) + { + executionContext.PolicyWrapKey = priorPolicyWrapKey; + executionContext.PolicyKey = priorPolicyKey; + } /// /// Updates the execution with context from the executing policy. @@ -27,16 +39,4 @@ public abstract partial class PolicyBase executionContext.PolicyKey = PolicyKey; } - - /// - /// Restores the supplied keys to the execution . - /// - /// The execution . - /// The prior to execution through this policy. - /// The prior to execution through this policy. - internal void RestorePolicyContext(Context executionContext, string priorPolicyWrapKey, string priorPolicyKey) - { - executionContext.PolicyWrapKey = priorPolicyWrapKey; - executionContext.PolicyKey = priorPolicyKey; - } } diff --git a/src/Polly/Polly.csproj b/src/Polly/Polly.csproj index 4efe5402c10..891f8f70313 100644 --- a/src/Polly/Polly.csproj +++ b/src/Polly/Polly.csproj @@ -11,8 +11,8 @@ $(NoWarn);IDE0044;IDE1006;CA1062;S107;CA1068;S4039;SA1121;CA1000;CA1063;SA1113;CA1031;CA1051;CA1200 $(NoWarn);SA1629;SA1612;CA2211;S2223;CA1032;CA1815;CA1816;S4457;SA1615;IDE0250;S109;SA1618;SA1407;CA1033 $(NoWarn);SA1515;S4023;CA1010;IDE0063;S2681;S3442;S3880;CA1064;SA1110;SA1203;SA1649;SA1625;SA1623;SA1118 - $(NoWarn);S3253;S3971;S6605;CA1724;CA1716;SA1108;CA1710;S4049;S3246;SA1204;S3928;CA1508;CA1822;CA2201;SA1642 - $(NoWarn);SA1805;SA1129;SA1805;CA1805;CA1821 + $(NoWarn);S3253;S3971;S6605;CA1724;CA1716;SA1108;CA1710;S4049;S3246 + $(NoWarn);SA1805;SA1805;CA1805;CA1821 $(NoWarn);RS0037; diff --git a/src/Polly/RateLimit/LockFreeTokenBucketRateLimiter.cs b/src/Polly/RateLimit/LockFreeTokenBucketRateLimiter.cs index 0e1ac2d8370..168a34eac52 100644 --- a/src/Polly/RateLimit/LockFreeTokenBucketRateLimiter.cs +++ b/src/Polly/RateLimit/LockFreeTokenBucketRateLimiter.cs @@ -15,7 +15,7 @@ internal sealed class LockFreeTokenBucketRateLimiter : IRateLimiter private long addNextTokenAtTicks; #if !NETSTANDARD2_0 - private SpinWait spinner = new(); + private SpinWait spinner = default; #endif /// diff --git a/src/Polly/RateLimit/RateLimitRejectedException.cs b/src/Polly/RateLimit/RateLimitRejectedException.cs index f785e322703..6820473e7fc 100644 --- a/src/Polly/RateLimit/RateLimitRejectedException.cs +++ b/src/Polly/RateLimit/RateLimitRejectedException.cs @@ -54,15 +54,15 @@ public RateLimitRejectedException(TimeSpan retryAfter, string message) : base(me public RateLimitRejectedException(TimeSpan retryAfter, string message, Exception innerException) : base(message, innerException) => SetRetryAfter(retryAfter); + private static string DefaultMessage(TimeSpan retryAfter) => + $"The operation has been rate-limited and should be retried after {retryAfter}"; + private void SetRetryAfter(TimeSpan retryAfter) { if (retryAfter < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(retryAfter), retryAfter, $"The {nameof(retryAfter)} parameter must be a TimeSpan greater than or equal to TimeSpan.Zero."); RetryAfter = retryAfter; } - private static string DefaultMessage(TimeSpan retryAfter) => - $"The operation has been rate-limited and should be retried after {retryAfter}"; - #if NETSTANDARD2_0 /// /// Initializes a new instance of the class. diff --git a/src/Polly/Registry/PolicyRegistry.cs b/src/Polly/Registry/PolicyRegistry.cs index 2547c02a4c8..e9a5106c403 100644 --- a/src/Polly/Registry/PolicyRegistry.cs +++ b/src/Polly/Registry/PolicyRegistry.cs @@ -10,7 +10,7 @@ public class PolicyRegistry : IConcurrentPolicyRegistry private readonly IDictionary _registry = new ConcurrentDictionary(); /// - /// Creates a registry of policies with keys. + /// Initializes a new instance of the class, with keys. /// public PolicyRegistry() { @@ -21,12 +21,12 @@ public PolicyRegistry() } /// - /// Creates a registry of policies with keys. + /// Initializes a new instance of the class, with dictionary. /// This internal constructor exists solely to facilitate testing of the GetEnumerator() methods, which allow us to support collection initialisation syntax. /// /// a dictionary containing keys and policies used for testing. internal PolicyRegistry(IDictionary registry) => - _registry = registry ?? throw new NullReferenceException(nameof(registry)); + _registry = registry ?? throw new ArgumentNullException(nameof(registry)); private ConcurrentDictionary ThrowIfNotConcurrentImplementation() { @@ -158,11 +158,14 @@ public bool TryRemove(string key, out TPolicy policy) where TPolicy : I /// /// Compares the existing policy for the specified key with a specified policy, and if they are equal, updates the policy with a third value. /// - /// + /// The type of the policy. /// The key whose value is compared with comparisonPolicy, and possibly replaced. /// The policy that replaces the value for the specified , if the comparison results in equality. /// The policy that is compared to the existing policy at the specified key. - /// + /// + /// if the value with was equal to and + /// replaced with ; otherwise, . + /// public bool TryUpdate(string key, TPolicy newPolicy, TPolicy comparisonPolicy) where TPolicy : IsPolicy { var registry = ThrowIfNotConcurrentImplementation(); diff --git a/src/Polly/Wrap/AsyncPolicyWrapSyntax.cs b/src/Polly/Wrap/AsyncPolicyWrapSyntax.cs index 331656823df..b2b262e9260 100644 --- a/src/Polly/Wrap/AsyncPolicyWrapSyntax.cs +++ b/src/Polly/Wrap/AsyncPolicyWrapSyntax.cs @@ -1,5 +1,59 @@ namespace Polly; +/// +/// Defines extensions for configuring instances on an or . +/// +public static class IAsyncPolicyPolicyWrapExtensions +{ + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); + } + + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); + } + + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); + } + + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); + } +} + public partial class AsyncPolicy { /// @@ -97,7 +151,7 @@ public static AsyncPolicyWrap WrapAsync(params IAsyncPolicy[] policies) /// The return type of delegates which may be executed through the policy. /// The PolicyWrap. /// The enumerable of policies to form the wrap must contain at least two policies. - public static AsyncPolicyWrap WrapAsync(params IAsyncPolicy[] policies) + public static AsyncPolicyWrap WrapAsync(params IAsyncPolicy[] policies) { switch (policies.Length) { @@ -112,57 +166,3 @@ public static AsyncPolicyWrap WrapAsync(params IAsyncPolicy -/// Defines extensions for configuring instances on an or . -/// -public static class IAsyncPolicyPolicyWrapExtensions -{ - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); - } - - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); - } - - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); - } - - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static AsyncPolicyWrap WrapAsync(this IAsyncPolicy outerPolicy, IAsyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((AsyncPolicy)outerPolicy).WrapAsync(innerPolicy); - } -} diff --git a/src/Polly/Wrap/PolicyWrapSyntax.cs b/src/Polly/Wrap/PolicyWrapSyntax.cs index 7dd1163dde1..d4b67db64f2 100644 --- a/src/Polly/Wrap/PolicyWrapSyntax.cs +++ b/src/Polly/Wrap/PolicyWrapSyntax.cs @@ -1,5 +1,59 @@ namespace Polly; +/// +/// Defines extensions for configuring instances on an or . +/// +public static class ISyncPolicyPolicyWrapExtensions +{ + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((Policy)outerPolicy).Wrap(innerPolicy); + } + + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((Policy)outerPolicy).Wrap(innerPolicy); + } + + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((Policy)outerPolicy).Wrap(innerPolicy); + } + + /// + /// Wraps the specified outer policy round the inner policy. + /// + /// The outer policy. + /// The inner policy. + /// A instance representing the combined wrap. + public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) + { + if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); + return ((Policy)outerPolicy).Wrap(innerPolicy); + } +} + public partial class Policy { /// @@ -112,57 +166,3 @@ public static PolicyWrap Wrap(params ISyncPolicy[] po } } } - -/// -/// Defines extensions for configuring instances on an or . -/// -public static class ISyncPolicyPolicyWrapExtensions -{ - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((Policy) outerPolicy).Wrap(innerPolicy); - } - - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((Policy)outerPolicy).Wrap(innerPolicy); - } - - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((Policy)outerPolicy).Wrap(innerPolicy); - } - - /// - /// Wraps the specified outer policy round the inner policy. - /// - /// The outer policy. - /// The inner policy. - /// A instance representing the combined wrap. - public static PolicyWrap Wrap(this ISyncPolicy outerPolicy, ISyncPolicy innerPolicy) - { - if (outerPolicy == null) throw new ArgumentNullException(nameof(outerPolicy)); - return ((Policy)outerPolicy).Wrap(innerPolicy); - } -}