-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
63 changed files
with
3,214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace Polly.Simmy.Behavior; | ||
|
||
#pragma warning disable CA1815 // Override equals and operator equals on value types | ||
|
||
/// <summary> | ||
/// Arguments used by the behavior chaos strategy to execute a user's delegate custom action. | ||
/// </summary> | ||
public readonly struct BehaviorActionArguments | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BehaviorActionArguments"/> struct. | ||
/// </summary> | ||
/// <param name="context">The context associated with the execution of a user-provided callback.</param> | ||
public BehaviorActionArguments(ResilienceContext context) => Context = context; | ||
|
||
/// <summary> | ||
/// Gets the ResilienceContext instance. | ||
/// </summary> | ||
public ResilienceContext Context { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using Polly.Telemetry; | ||
|
||
namespace Polly.Simmy.Behavior; | ||
|
||
internal sealed class BehaviorChaosStrategy : MonkeyStrategy | ||
{ | ||
private readonly ResilienceStrategyTelemetry _telemetry; | ||
|
||
public BehaviorChaosStrategy( | ||
BehaviorStrategyOptions options, | ||
ResilienceStrategyTelemetry telemetry) | ||
: base(options) | ||
{ | ||
_telemetry = telemetry; | ||
OnBehaviorInjected = options.OnBehaviorInjected; | ||
Behavior = options.BehaviorAction!; | ||
} | ||
|
||
public Func<OnBehaviorInjectedArguments, ValueTask>? OnBehaviorInjected { get; } | ||
|
||
public Func<BehaviorActionArguments, ValueTask> Behavior { get; } | ||
|
||
protected internal override async ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState>( | ||
Func<ResilienceContext, TState, ValueTask<Outcome<TResult>>> callback, | ||
ResilienceContext context, | ||
TState state) | ||
{ | ||
try | ||
{ | ||
if (await ShouldInjectAsync(context).ConfigureAwait(context.ContinueOnCapturedContext)) | ||
{ | ||
await Behavior(new(context)).ConfigureAwait(context.ContinueOnCapturedContext); | ||
|
||
var args = new OnBehaviorInjectedArguments(context); | ||
_telemetry.Report(new(ResilienceEventSeverity.Information, BehaviorConstants.OnBehaviorInjectedEvent), context, args); | ||
|
||
if (OnBehaviorInjected is not null) | ||
{ | ||
await OnBehaviorInjected(args).ConfigureAwait(context.ContinueOnCapturedContext); | ||
} | ||
} | ||
|
||
return await StrategyHelper.ExecuteCallbackSafeAsync(callback, context, state).ConfigureAwait(context.ContinueOnCapturedContext); | ||
} | ||
catch (OperationCanceledException e) | ||
{ | ||
return new Outcome<TResult>(e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Polly.Simmy.Behavior; | ||
|
||
internal static class BehaviorConstants | ||
{ | ||
public const string OnBehaviorInjectedEvent = "OnBehaviorInjected"; | ||
} |
57 changes: 57 additions & 0 deletions
57
src/Polly.Core/Simmy/Behavior/BehaviorPipelineBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Diagnostics.CodeAnalysis; | ||
using Polly.Simmy.Behavior; | ||
|
||
namespace Polly.Simmy; | ||
|
||
/// <summary> | ||
/// Extension methods for adding custom behaviors to a <see cref="ResiliencePipelineBuilder"/>. | ||
/// </summary> | ||
public static class BehaviorPipelineBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Adds a behavior chaos strategy to the builder. | ||
/// </summary> | ||
/// <typeparam name="TBuilder">The builder type.</typeparam> | ||
/// <param name="builder">The builder instance.</param> | ||
/// <param name="enabled">A value that indicates whether or not the chaos strategy is enabled for a given execution.</param> | ||
/// <param name="injectionRate">The injection rate for a given execution, which the value should be between [0, 1] (inclusive).</param> | ||
/// <param name="behavior">The behavior to be injected.</param> | ||
/// <returns>The same builder instance.</returns> | ||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder"/> is <see langword="null"/>.</exception> | ||
/// <exception cref="ValidationException">Thrown when the options produced from the arguments are invalid.</exception> | ||
public static TBuilder AddChaosBehavior<TBuilder>(this TBuilder builder, bool enabled, double injectionRate, Func<ValueTask> behavior) | ||
where TBuilder : ResiliencePipelineBuilderBase | ||
{ | ||
Guard.NotNull(builder); | ||
|
||
return builder.AddChaosBehavior(new BehaviorStrategyOptions | ||
{ | ||
Enabled = enabled, | ||
InjectionRate = injectionRate, | ||
BehaviorAction = (_) => behavior() | ||
}); | ||
} | ||
|
||
/// <summary> | ||
/// Adds a behavior chaos strategy to the builder. | ||
/// </summary> | ||
/// <typeparam name="TBuilder">The builder type.</typeparam> | ||
/// <param name="builder">The builder instance.</param> | ||
/// <param name="options">The behavior options.</param> | ||
/// <returns>The same builder instance.</returns> | ||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder"/> or <paramref name="options"/> is <see langword="null"/>.</exception> | ||
/// <exception cref="ValidationException">Thrown when <paramref name="options"/> are invalid.</exception> | ||
[UnconditionalSuppressMessage( | ||
"Trimming", | ||
"IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", | ||
Justification = "All options members preserved.")] | ||
public static TBuilder AddChaosBehavior<TBuilder>(this TBuilder builder, BehaviorStrategyOptions options) | ||
where TBuilder : ResiliencePipelineBuilderBase | ||
{ | ||
Guard.NotNull(builder); | ||
Guard.NotNull(options); | ||
|
||
return builder.AddStrategy(context => new BehaviorChaosStrategy(options, context.Telemetry), options); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace Polly.Simmy.Behavior; | ||
|
||
/// <summary> | ||
/// Represents the options for the Behavior chaos strategy. | ||
/// </summary> | ||
public class BehaviorStrategyOptions : MonkeyStrategyOptions | ||
{ | ||
/// <summary> | ||
/// Gets or sets the delegate that's raised when the custom behavior is injected. | ||
/// </summary> | ||
/// <remarks> | ||
/// Defaults to <see langword="null"/>. | ||
/// </remarks> | ||
public Func<OnBehaviorInjectedArguments, ValueTask>? OnBehaviorInjected { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the custom behavior that is going to be injected for a given execution. | ||
/// </summary> | ||
/// <remarks> | ||
/// Defaults to <see langword="null"/>. | ||
/// </remarks> | ||
[Required] | ||
public Func<BehaviorActionArguments, ValueTask>? BehaviorAction { get; set; } | ||
} |
20 changes: 20 additions & 0 deletions
20
src/Polly.Core/Simmy/Behavior/OnBehaviorInjectedArguments.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace Polly.Simmy.Behavior; | ||
|
||
#pragma warning disable CA1815 // Override equals and operator equals on value types | ||
|
||
/// <summary> | ||
/// Arguments used by the behavior chaos strategy to notify that a custom behavior was injected. | ||
/// </summary> | ||
public readonly struct OnBehaviorInjectedArguments | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="OnBehaviorInjectedArguments"/> struct. | ||
/// </summary> | ||
/// <param name="context">The context associated with the execution of a user-provided callback.</param> | ||
public OnBehaviorInjectedArguments(ResilienceContext context) => Context = context; | ||
|
||
/// <summary> | ||
/// Gets the ResilienceContext instance. | ||
/// </summary> | ||
public ResilienceContext Context { get; } | ||
} |
Oops, something went wrong.