Skip to content

Commit

Permalink
Cleanup samples (#1544)
Browse files Browse the repository at this point in the history
  • Loading branch information
martintmk committed Sep 4, 2023
1 parent 445c582 commit da9db1b
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 39 deletions.
3 changes: 2 additions & 1 deletion samples/DependencyInjection/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
// ------------------------------------------------------------------------
// 1. Register your resilience pipeline
// ------------------------------------------------------------------------

var serviceProvider = new ServiceCollection()
.AddLogging(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Debug))

// Use "AddResiliencePipeline" extension method to configure your named pipeline
.AddResiliencePipeline("my-pipeline", (builder, context) =>
{
Expand All @@ -18,6 +18,7 @@
builder.AddTimeout(TimeSpan.FromSeconds(1));
})

// You can also register result-based (generic) resilience pipelines
// First generic parameter is the key type, the second one is the result type
// This overload does not use the context argument (simple scenarios)
Expand Down
7 changes: 7 additions & 0 deletions samples/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<Project>

<PropertyGroup>
<RunAnalyzers>true</RunAnalyzers>
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisLevel>latest</AnalysisLevel>
<ProjectType>Library</ProjectType>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<NoWarn>$(NoWarn);SA1123;SA1515;CA2000;CA2007;CA1303;IDE0021;RS0037;RS0016;CS1591</NoWarn>
</PropertyGroup>

<Import Project="$(MsBuildThisFileDirectory)..\eng\Library.targets" />

</Project>
32 changes: 15 additions & 17 deletions samples/Extensibility/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
{
Console.WriteLine("OnCustomEvent");
return default;
}
},
})
.Build();

Expand All @@ -22,7 +22,6 @@
// ------------------------------------------------------------------------
// SIMPLE EXTENSIBILITY MODEL (INLINE STRATEGY)
// ------------------------------------------------------------------------

pipeline = new ResiliencePipelineBuilder()
// Just add the strategy instance directly
.AddStrategy(_ => new MySimpleStrategy(), new MySimpleStrategyOptions())
Expand Down Expand Up @@ -77,13 +76,13 @@ public class MySimpleStrategyOptions : ResilienceStrategyOptions
// For reactive strategies, you can use ReactiveResilienceStrategy<T> as base class.
internal class MyResilienceStrategy : ResilienceStrategy
{
private readonly ResilienceStrategyTelemetry telemetry;
private readonly Func<OnCustomEventArguments, ValueTask>? onCustomEvent;
private readonly ResilienceStrategyTelemetry _telemetry;
private readonly Func<OnCustomEventArguments, ValueTask>? _onCustomEvent;

public MyResilienceStrategy(ResilienceStrategyTelemetry telemetry, MySimpleStrategyOptions options)
{
this.telemetry = telemetry;
this.onCustomEvent = options.OnCustomEvent;
_telemetry = telemetry;
_onCustomEvent = options.OnCustomEvent;
}

protected override async ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState>(
Expand All @@ -101,15 +100,15 @@ protected override async ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState
// ...

// You can then report important telemetry events
telemetry.Report(
_telemetry.Report(
new ResilienceEvent(ResilienceEventSeverity.Information, "MyCustomEvent"),
context,
new OnCustomEventArguments(context));

// Call the delegate if provided by the user
if (onCustomEvent is not null)
if (_onCustomEvent is not null)
{
await onCustomEvent(new OnCustomEventArguments(context));
await _onCustomEvent(new OnCustomEventArguments(context));
}

return outcome;
Expand All @@ -119,15 +118,14 @@ protected override async ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState
// ------------------------------------------------------------------------
// 3. Expose new extensions for ResiliencePipelineBuilder
// ------------------------------------------------------------------------

public static class MyResilienceStrategyExtensions
{
// Add new extension that works for both "ResiliencePipelineBuilder" and "ResiliencePipelineBuilder<T>"
public static TBuilder AddMyResilienceStrategy<TBuilder>(this TBuilder builder, MySimpleStrategyOptions options) where TBuilder : ResiliencePipelineBuilderBase
=> builder.AddStrategy(
// Provide a factory that creates the strategy
context => new MyResilienceStrategy(context.Telemetry, options),

// Pass the options, note that the options instance is automatically validated by the builder
options);
public static TBuilder AddMyResilienceStrategy<TBuilder>(this TBuilder builder, MySimpleStrategyOptions options)
where TBuilder : ResiliencePipelineBuilderBase
{
return builder.AddStrategy(
context => new MyResilienceStrategy(context.Telemetry, options), // Provide a factory that creates the strategy
options); // Pass the options, note that the options instance is automatically validated by the builder
}
}
17 changes: 11 additions & 6 deletions samples/GenericStrategies/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Net;
#pragma warning disable SA1633 // File should have header
using System.Net;
#pragma warning restore SA1633 // File should have header
using Polly;
using Polly.Fallback;
using Polly.Retry;
Expand All @@ -10,7 +12,6 @@

// The generic ResiliencePipelineBuilder<T> creates a ResiliencePipeline<T>
// that can execute synchronous and asynchronous callbacks that return T.

ResiliencePipeline<HttpResponseMessage> pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
.AddFallback(new FallbackStrategyOptions<HttpResponseMessage>
{
Expand All @@ -19,26 +20,28 @@
// Return fallback result
return Outcome.FromResultAsValueTask(new HttpResponseMessage(HttpStatusCode.OK));
},

// You can also use switch expressions for succinct syntax
ShouldHandle = arguments => arguments.Outcome switch
{
// The "PredicateResult.True" is shorthand to "new ValueTask<bool>(true)"
{ Exception: HttpRequestException } => PredicateResult.True(),
{ Result: HttpResponseMessage response } when response.StatusCode == HttpStatusCode.InternalServerError => PredicateResult.True(),
_ => PredicateResult.False()
_ => PredicateResult.False(),
},
OnFallback = _ =>
{
Console.WriteLine("Fallback!");
return default;
}
},
})
.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
{
// You can use "PredicateBuilder" to configure the predicates
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.HandleResult(r => r.StatusCode == HttpStatusCode.InternalServerError)
.Handle<HttpRequestException>(),

// Register user callback called whenever retry occurs
OnRetry = arguments =>
{
Expand All @@ -47,24 +50,26 @@
},
Delay = TimeSpan.FromMilliseconds(400),
BackoffType = DelayBackoffType.Constant,
MaxRetryAttempts = 3
MaxRetryAttempts = 3,
})
.AddTimeout(new TimeoutStrategyOptions
{
Timeout = TimeSpan.FromSeconds(1),

// Register user callback called whenever timeout occurs
OnTimeout = _ =>
{
Console.WriteLine("Timeout occurred!");
return default;
}
},
})
.Build();

var response = await pipeline.ExecuteAsync(
async token =>
{
await Task.Delay(10, token);
// This causes the action fail, thus using the fallback strategy above
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
},
Expand Down
22 changes: 16 additions & 6 deletions samples/Intro/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
// that can be executed synchronously or asynchronously
// and for both void and result-returning user-callbacks.
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()

// Use convenience extension that accepts TimeSpan
.AddTimeout(TimeSpan.FromSeconds(5))
.AddTimeout(TimeSpan.FromSeconds(5))
.Build();

// ------------------------------------------------------------------------
Expand All @@ -28,16 +29,22 @@
pipeline.Execute(token => "some-result");

// Asynchronously with result
await pipeline.ExecuteAsync(async token => { await Task.Delay(10, token); return "some-result"; }, CancellationToken.None);
await pipeline.ExecuteAsync(
async token =>
{
await Task.Delay(10, token);
return "some-result";
},
CancellationToken.None);

// Use state to avoid lambda allocation
pipeline.Execute(static state => state, "my-state");

// ------------------------------------------------------------------------
// 3. Create and execute a pipeline of strategies
// ------------------------------------------------------------------------

pipeline = new ResiliencePipelineBuilder()

// Add retries using the options
.AddRetry(new RetryStrategyOptions
{
Expand All @@ -48,8 +55,9 @@
// The "PredicateResult.False" is just shorthand for "new ValueTask<bool>(true)"
// You can also use "new PredicateBuilder().Handle<TimeoutRejectedException>()"
_ => PredicateResult.False()
_ => PredicateResult.False(),
},

// Register user callback called whenever retry occurs
OnRetry = args =>
{
Expand All @@ -58,18 +66,20 @@
},
Delay = TimeSpan.FromMilliseconds(400),
BackoffType = DelayBackoffType.Constant,
MaxRetryAttempts = 3
MaxRetryAttempts = 3,
})

// Add timeout using the options
.AddTimeout(new TimeoutStrategyOptions
{
Timeout = TimeSpan.FromSeconds(1),

// Register user callback called whenever timeout occurs
OnTimeout = args =>
{
Console.WriteLine($"Timeout occurred after {args.Timeout}!");
return default;
}
},
})
.Build();

Expand Down
2 changes: 1 addition & 1 deletion samples/Retries/ExecuteHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Retries;

internal class ExecuteHelper
internal sealed class ExecuteHelper
{
public bool Fail { get; set; } = true;

Expand Down
13 changes: 5 additions & 8 deletions samples/Retries/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// ------------------------------------------------------------------------
// 1. Create a retry pipeline that handles all exceptions
// ------------------------------------------------------------------------

ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
// Default retry options handle all exceptions
.AddRetry(new RetryStrategyOptions())
Expand All @@ -20,7 +19,6 @@
// ------------------------------------------------------------------------
// 2. Customize the retry behavior
// ------------------------------------------------------------------------

pipeline = new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions
{
Expand All @@ -32,7 +30,7 @@
// The recommended backoff type for HTTP scenarios
// See here for more information: https://github.com/App-vNext/Polly/wiki/Retry-with-jitter#more-complex-jitter
BackoffType = DelayBackoffType.Exponential,
UseJitter = true
UseJitter = true,
})
.Build();

Expand All @@ -42,7 +40,6 @@
// ------------------------------------------------------------------------
// 3. Register the callbacks
// ------------------------------------------------------------------------

pipeline = new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions
{
Expand All @@ -56,7 +53,7 @@
{
Console.WriteLine($"Retrying attempt {outcome.AttemptNumber}...");
return default;
}
},
})
.Build();

Expand All @@ -66,15 +63,15 @@
// ------------------------------------------------------------------------
// 4. Create an HTTP retry pipeline that handles both exceptions and results
// ------------------------------------------------------------------------

ResiliencePipeline<HttpResponseMessage> httpPipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
{
// Specify what exceptions or results should be retried
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.Handle<HttpRequestException>()
.Handle<InvalidOperationException>()
.HandleResult(r=>r.StatusCode == HttpStatusCode.InternalServerError),
.HandleResult(r => r.StatusCode == HttpStatusCode.InternalServerError),

// Specify delay generator
DelayGenerator = arguments =>
{
Expand All @@ -87,7 +84,7 @@
// Return delay hinted by the retry strategy
return new ValueTask<TimeSpan?>(default(TimeSpan?));
}
},
})
.Build();

Expand Down
1 change: 1 addition & 0 deletions samples/Samples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE7916FD-6C1A-48CE-8919-F4BAB4E3770F}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
README.md = README.md
Expand Down

0 comments on commit da9db1b

Please sign in to comment.