-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Polly v6 breaking changes
Polly v6 introduced a number of breaking changes over v5.
Area | Summary rationale |
---|---|
Rationalise Execute() / ExecuteAsync() overloads |
Reduce the number of overloads; standardise to build a more consistent overload set going forward |
Rename ExecutionKey as OperationKey
|
Better communicate purpose; reduce confusion with similar-named key. |
Rename ExecutionGuid as CorrelationId
|
Better communicate purpose; reduce confusion with similar-named key. |
Publish Polly as strong-named only | Avoid diamond-dependency conflicts in the market going forward |
Upgrade supported targets | Modernise |
All changes are deprecated in Polly v5.9 with [Obsolete]
attributes.
As well as taking the delegate to execute, Polly Execute()
/ ExecuteAsync()
overloads commonly offer the following two optional parameters:
Parameter | Purpose |
---|---|
Context |
an execution Context , or dictionary data to populate that context |
CancellationToken |
a CancellationToken , when you want to pass a token to control cancellation of the policy or the executing delegate |
In Polly v5, some overloads existed where the Context context
or CancellationToken
parameters were passed but not used as input parameters to the Func<Task> action
executed:
Task ExecuteAsync(Func<Task> action, Context context)
With such overloads the passed Context
or CancellationToken
parameters influenced policy behaviour, but not executed delegate behaviour.
In v6 all such overloads were deprecated in favour of overloads where the action
delegate executed takes all passed parameters
Task ExecuteAsync(Func<Context, Task> action, Context context)
By aligning the parameters passed to ExecuteAsync(...)
with the input parameters to the executed delegate, we open up the possibility for adding future generic overloads allowing user-defined input parameters to be passed into executed delegate without the use of closures:
Task<TResult> ExecuteAsync<T1, TResult>(Func<T1, Context, CancellationToken, Task<TResult>> func, T1 t1, Context context, CancellationToken token)
Task<TResult> ExecuteAsync<T1, T2, TResult>(Func<T1, T2, Context, CancellationToken, Task<TResult>> func, T1 t1, T2 t2, Context context, CancellationToken token)
Without the v6 standardisation of overloads this would not be possible.
If you receive a compilation error that the overload no longer exists in v6, simply add Context
or CancellationToken
(as appropriate) as an input to the executed delegate.
ExecuteAsync()
overloads also offer the bool continueOnCapturedContext
optional parameter. This has never featured as an input parameter to async delegates executed through policies and no changes was made to this.
The following properties on Context
were renamed:
Old name | New name |
---|---|
ExecutionKey |
OperationKey |
ExecutionGuid |
CorrelationId |
Use the new property names.
To v5.9 Polly was published as separate nuget packages Polly
(unsigned) and Polly-Signed
. Signed in the <=v5.9 context actually means strong-named.
From Polly v6.0 only a single package, Polly
, is published, and it is strong-named.
ASPNET Core 2.1 offers deep integration with Polly for HttpClient
instances created through HttpClientFactory
. This allows the easy application of Polly resilience strategies to outbound calls through HttpClient
.
ASPNET Core 2.1 is strong-named so this was expected to significantly increase consumption of a strong-named form of Polly. That however would risk creating diamond-dependency conflicts which apparently have no solution for packages or projects that before then consumed non-strong-named Polly (example) (good summary).
If we had left both non-strong-named and strong-named Polly in the market, we would have prolonged the possibility of these irresoluble conflicts into future months and years. By switching to a single, strong-named Polly release, there was initial impact while products switch to strong-named Polly but the duration of pain is limited by there being only a single version in the market. The single strong-named package strategy is the strategy used by high-download nuget packages such as NewtonSoft.Json, FluentValidation, and Serilog, and is the strategy recommended by the Microsoft ASP.NET team.
Polly v6.0 also adopts the so-called Newtonsoft.Json strategy described here to minimise onward impact:
- nuget package numbers follow full semver (Major.Minor.Patch increments) to differentiate bug-fixes, new-functionality-without-breaking-changes, and breaking-changes.
- Dlls partially follow Major.0.0 version numbering only (even if the true version is Major.Minor.Patch). This reduces the burden on projects which consume Polly of introducing excessive assembly binding redirects.
Reference: Further discussion.
Switch packages as follows:
Old package used | New package to use |
---|---|
Polly-Signed | Polly |
Polly | Polly |
Both non-strong-named DLLs and strong-named DLLs can reference strong-named DLLs, so whether your project uses strong-naming or not, you will be able to reference the new Polly v6 strong-named packages.
- Home
- Polly RoadMap
- Contributing
- Transient fault handling and proactive resilience engineering
- Supported targets
- Retry
- Circuit Breaker
- Advanced Circuit Breaker
- Timeout
- Bulkhead
- Cache
- Rate-Limit
- Fallback
- PolicyWrap
- NoOp
- PolicyRegistry
- Polly and HttpClientFactory
- Asynchronous action execution
- Handling InnerExceptions and AggregateExceptions
- Statefulness of policies
- Keys and Context Data
- Non generic and generic policies
- Polly and interfaces
- Some policy patterns
- Debugging with Polly in Visual Studio
- Unit-testing with Polly
- Polly concept and architecture
- Polly v6 breaking changes
- Polly v7 breaking changes
- DISCUSSION PROPOSAL- Polly eventing and metrics architecture