Skip to content

Commit

Permalink
Updates for alpha.9 (#1526)
Browse files Browse the repository at this point in the history
- Update CHANGELOG.
- Bump samples to 8.0.0-alpha.9.
  • Loading branch information
martincostello committed Aug 30, 2023
1 parent 58c8fac commit a0be561
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 87 deletions.
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
## 8.0.0-alpha.9

* Updates for alpha.8 by [@martincostello](https://github.com/martincostello) in https://github.com/App-vNext/Polly/pull/1465
* Fix unstable build by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1466
* Improve samples by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1467
* Specify DebuggerDisplay for ReactiveResilienceStrategyBridge by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1468
* Drop the `Extensions` from `Polly.Extensions` namespace by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1469
* Remove Moq by [@martincostello](https://github.com/martincostello) in https://github.com/App-vNext/Polly/pull/1472
* Add new metering tests to cover uncovered lines by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1474
* Default names for individual resilience strategies by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1475
* Introduce `NonReactiveResilienceStrategy` by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1476
* Drop `TelemetryResilienceStrategy` by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1482
* API Review feedback (1) by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1484
* Rename ResilienceStrategy to ResiliencePipeline by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1483
* API Review Feedback (2) by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1485
* Introduce TelemetryListener by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1486
* Improve documentation by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1487
* Fix metering tests by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1488
* Hide validation APIs by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1490
* Logging improvements by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1489
* Hide/drop some unused APIs by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1491
* Cleanup internals by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1492
* ResilienceContextPool improvements by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1493
* Hide IsSynchronous property by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1494
* Drop unused ResiliencePipelineRegistry APIs by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1495
* `ResiliencePipelineRegistry` is now disposable by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1496
* Move pipeline-related internals into `Pipeline` folder by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1497
* Update benchmarks by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1503
* Minor ResiliencePipelineRegistry cleanup of internals by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1505
* API Review Feedback by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1506
* Minor API cleanup by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1508
* Clenaup rate limiter API by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1509
* Cleanup ResiliencePipelineRegistry internals by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1510
* Allow to dispose linked resources on pipeline disposal by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1511
* Simplify and enhance the pipeline reloads by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1512
* Drop `OutcomeArguments` struct by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1513
* API Review Feedback by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1520
* Got rid of some warnings in the Polly project by [@IgorIgorevich94](https://github.com/IgorIgorevich94) in https://github.com/App-vNext/Polly/pull/1514
* API Review Feedback by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1521
* Cleanup Outcome internals and drop unused hedging and fallbacks APIs by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1523
* Improve debugging experience for `ResilienceProperties` by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1524
* Protect against retry delay overflows by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1522
* Fix DelayAsync extension by [@martintmk](https://github.com/martintmk) in https://github.com/App-vNext/Polly/pull/1525

## 8.0.0-alpha.8

* Updates for 8.0.0-alpha.7 by [@martincostello](https://github.com/martincostello) in https://github.com/App-vNext/Polly/pull/1433
Expand Down
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<MicrosoftExtensionsVersion>7.0.0</MicrosoftExtensionsVersion>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<PollyVersion>8.0.0-alpha.8</PollyVersion>
<PollyVersion>8.0.0-alpha.9</PollyVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
> Major performance improvements are on the way! Please see our [blog post](https://www.thepollyproject.org/2023/03/03/we-want-your-feedback-introducing-polly-v8/) to learn more and provide feedback in the [related GitHub issue](https://github.com/App-vNext/Polly/issues/1048).
>
> :rotating_light::rotating_light: **Polly v8 feature-complete!** :rotating_light::rotating_light:
> - Polly v8 Alpha 8 is now available on [NuGet.org](https://www.nuget.org/packages/Polly/8.0.0-alpha.8)
> - The Alpha 8 version is considered feature-complete. After completing [review of the API](https://github.com/App-vNext/Polly/pull/1233) to address unresolved issues, we will move on to a Beta release.
> - Polly v8 Alpha 9 is now available on [NuGet.org](https://www.nuget.org/packages/Polly/8.0.0-alpha.9)
> - The Alpha 9 version is considered feature-complete. After completing [review of the API](https://github.com/App-vNext/Polly/pull/1233) to address unresolved issues, we will move on to a Beta release.
> - The v8 docs are not yet finished, but you can take a look at sample code in these locations:
> - Within the repo's new [Samples folder](https://github.com/App-vNext/Polly/tree/main/samples)
> - By reading `Polly.Core`'s [README](https://github.com/App-vNext/Polly/blob/main/src/Polly.Core/README.md)
Expand Down
32 changes: 16 additions & 16 deletions samples/DependencyInjection/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,49 @@
using Polly.Timeout;

// ------------------------------------------------------------------------
// 1. Register your resilience strategy
// 1. Register your resilience pipeline
// ------------------------------------------------------------------------

var serviceProvider = new ServiceCollection()
.AddLogging(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Debug))
// Use "AddResilienceStrategy" extension method to configure your named strategy
.AddResilienceStrategy("my-strategy", (builder, context) =>
// Use "AddResiliencePipeline" extension method to configure your named pipeline
.AddResiliencePipeline("my-pipeline", (builder, context) =>
{
// You can resolve any service from DI when building the strategy
// You can resolve any service from DI when building the pipeline
context.ServiceProvider.GetRequiredService<ILoggerFactory>();
builder.AddTimeout(TimeSpan.FromSeconds(1));
})
// You can also register result-based (generic) resilience strategies
// 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)
.AddResilienceStrategy<string, HttpResponseMessage>("my-http-strategy", builder =>
.AddResiliencePipeline<string, HttpResponseMessage>("my-http-pipeline", builder =>
{
builder.AddTimeout(TimeSpan.FromSeconds(1));
})
.BuildServiceProvider();

// ------------------------------------------------------------------------
// 2. Retrieve and use your resilience strategy
// 2. Retrieve and use your resilience pipeline
// ------------------------------------------------------------------------

// Resolve the resilience strategy provider for string-based keys
ResilienceStrategyProvider<string> strategyProvider = serviceProvider.GetRequiredService<ResilienceStrategyProvider<string>>();
// Resolve the resilience pipeline provider for string-based keys
ResiliencePipelineProvider<string> pipelineProvider = serviceProvider.GetRequiredService<ResiliencePipelineProvider<string>>();

// Retrieve the strategy by name
ResilienceStrategy strategy = strategyProvider.GetStrategy("my-strategy");
// Retrieve the pipeline by name
ResiliencePipeline pipeline = pipelineProvider.GetPipeline("my-pipeline");

// Retrieve the generic strategy by name
ResilienceStrategy<HttpResponseMessage> genericStrategy = strategyProvider.GetStrategy<HttpResponseMessage>("my-http-strategy");
// Retrieve the generic pipeline by name
ResiliencePipeline<HttpResponseMessage> genericPipeline = pipelineProvider.GetPipeline<HttpResponseMessage>("my-http-pipeline");

try
{
// Execute the strategy
// Execute the pipeline
// Notice in console output that telemetry is automatically enabled
await strategy.ExecuteAsync(async token => await Task.Delay(10000, token), CancellationToken.None);
await pipeline.ExecuteAsync(async token => await Task.Delay(10000, token), CancellationToken.None);
}
catch (TimeoutRejectedException)
{
// The timeout strategy cancels the user callback and throws this exception
// The timeout pipeline cancels the user callback and throws this exception
Console.WriteLine("Timeout!");
}
33 changes: 14 additions & 19 deletions samples/Extensibility/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
// ------------------------------------------------------------------------
// Usage of custom strategy
// ------------------------------------------------------------------------
var strategy = new CompositeStrategyBuilder()
var pipeline = new ResiliencePipelineBuilder()
// This is custom extension defined in this sample
.AddMyResilienceStrategy(new MyResilienceStrategyOptions
.AddMyResilienceStrategy(new MySimpleStrategyOptions
{
OnCustomEvent = args =>
{
Expand All @@ -16,20 +16,20 @@
})
.Build();

// Execute the strategy
strategy.Execute(() => { });
// Execute the pipeline
pipeline.Execute(() => { });

// ------------------------------------------------------------------------
// SIMPLE EXTENSIBILITY MODEL (INLINE STRATEGY)
// ------------------------------------------------------------------------

strategy = new CompositeStrategyBuilder()
pipeline = new ResiliencePipelineBuilder()
// Just add the strategy instance directly
.AddStrategy(new MySimpleStrategy())
.AddStrategy(_ => new MySimpleStrategy(), new MySimpleStrategyOptions())
.Build();

// Execute the strategy
strategy.Execute(() => { });
// Execute the pipeline
pipeline.Execute(() => { });

internal class MySimpleStrategy : ResilienceStrategy
{
Expand All @@ -40,11 +40,6 @@ protected override ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState>(
{
Console.WriteLine("MySimpleStrategy executing!");

// The "context" holds information about execution mode
Console.WriteLine("context.IsSynchronous: {0}", context.IsSynchronous);
Console.WriteLine("context.ResultType: {0}", context.ResultType);
Console.WriteLine("context.IsVoid: {0}", context.IsVoid);

// The "state" is an ambient value passed by the caller that holds the state.
// Here, we do not do anything with it, just pass it to the callback.

Expand All @@ -65,7 +60,7 @@ protected override ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState>(
public readonly record struct OnCustomEventArguments(ResilienceContext Context);

// 1.B Define the options.
public class MyResilienceStrategyOptions : ResilienceStrategyOptions
public class MySimpleStrategyOptions : ResilienceStrategyOptions
{
// Use the arguments in the delegates.
// The recommendation is to use asynchronous delegates.
Expand All @@ -79,13 +74,13 @@ public class MyResilienceStrategyOptions : ResilienceStrategyOptions
// The strategy should be internal and not exposed as part of any public API.
// Instead, expose options and extensions for resilience strategy builder.
//
// For reactive startegies, you can use ReactiveResilienceStrategy<T> as base class.
// 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;

public MyResilienceStrategy(ResilienceStrategyTelemetry telemetry, MyResilienceStrategyOptions options)
public MyResilienceStrategy(ResilienceStrategyTelemetry telemetry, MySimpleStrategyOptions options)
{
this.telemetry = telemetry;
this.onCustomEvent = options.OnCustomEvent;
Expand Down Expand Up @@ -122,13 +117,13 @@ protected override async ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState
}

// ------------------------------------------------------------------------
// 3. Expose new extensions for CompositeStrategyBuilder
// 3. Expose new extensions for ResiliencePipelineBuilder
// ------------------------------------------------------------------------

public static class MyResilienceStrategyExtensions
{
// Add new extension that works for both "CompositeStrategyBuilder" and "CompositeStrategyBuilder<T>"
public static TBuilder AddMyResilienceStrategy<TBuilder>(this TBuilder builder, MyResilienceStrategyOptions options) where TBuilder : CompositeStrategyBuilderBase
// 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),
Expand Down
38 changes: 25 additions & 13 deletions samples/GenericStrategies/Program.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
using Polly;
using System.Net;
using Polly;
using Polly.Fallback;
using Polly.Retry;
using Polly.Timeout;
using System.Net;

// ----------------------------------------------------------------------------
// Create a generic resilience strategy using CompositeStrategyBuilder<T>
// Create a generic resilience pipeline using ResiliencePipelineBuilder<T>
// ----------------------------------------------------------------------------

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

ResilienceStrategy<HttpResponseMessage> strategy = new CompositeStrategyBuilder<HttpResponseMessage>()
ResiliencePipeline<HttpResponseMessage> pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
.AddFallback(new FallbackStrategyOptions<HttpResponseMessage>
{
FallbackAction = _ =>
Expand All @@ -20,14 +20,18 @@
return Outcome.FromResultAsTask(new HttpResponseMessage(HttpStatusCode.OK));
},
// You can also use switch expressions for succinct syntax
ShouldHandle = outcome => outcome switch
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
},
OnFallback = _ => { Console.WriteLine("Fallback!"); return default; }
OnFallback = _ =>
{
Console.WriteLine("Fallback!");
return default;
}
})
.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
{
Expand All @@ -36,20 +40,28 @@
.HandleResult(r => r.StatusCode == HttpStatusCode.InternalServerError)
.Handle<HttpRequestException>(),
// Register user callback called whenever retry occurs
OnRetry = outcome => { Console.WriteLine($"Retrying '{outcome.Result?.StatusCode}'..."); return default; },
BaseDelay = TimeSpan.FromMilliseconds(400),
BackoffType = RetryBackoffType.Constant,
RetryCount = 3
OnRetry = arguments =>
{
Console.WriteLine($"Retrying '{arguments.Outcome.Result?.StatusCode}'...");
return default;
},
Delay = TimeSpan.FromMilliseconds(400),
BackoffType = DelayBackoffType.Constant,
MaxRetryAttempts = 3
})
.AddTimeout(new TimeoutStrategyOptions
{
Timeout = TimeSpan.FromSeconds(1),
// Register user callback called whenever timeout occurs
OnTimeout = _ => { Console.WriteLine("Timeout occurred!"); return default; }
OnTimeout = _ =>
{
Console.WriteLine("Timeout occurred!");
return default;
}
})
.Build();

var response = await strategy.ExecuteAsync(
var response = await pipeline.ExecuteAsync(
async token =>
{
await Task.Delay(10, token);
Expand Down
Loading

0 comments on commit a0be561

Please sign in to comment.