Skip to content

Polly v7 breaking changes

martincostello edited this page Sep 28, 2023 · 8 revisions

Polly v7 breaking changes

ℹ️ This documentation describes the previous Polly v7 API. If you are using the new v8 API, please refer to pollydocs.org.

Polly v7 contains the following breaking changes over v6.

Change Summary rationale
Clarify the separation of synchronous and asynchronous policies in Polly Remove ugly runtime exception;
replace with compile-time validation
Allow cache policies to cache values of type TResult.
Changes signature of ISyncCacheProvider, IAsyncCacheProvider, and their generic equivalents.
Prior this change it was not possible to cache (for example) false of an execution returning a bool

No deprecations with [Obsolete] attributes were published for the sync/async changes, because the removed behaviours were runtime exceptions (not valid functionality) in any case.

Clarify the separation of synchronous and asynchronous policies

What changed?

To Polly v6, it was possibly to call a synchronous .Execute() method on a concrete class of an asynchronously-configured policy (eg .RetryAsync()) - and vice versa - resulting in a runtime exception.

Polly v6 had already reduced the impact of this legacy behaviour by introducing execution interfaces limiting the execution overloads to those appropriate for the policy type (sync for sync policies; async for async policies). You will see no change in behaviour if you have already been referencing policies via the policy execution interfaces:

IAsyncPolicy retryPolicy = Policy.Handle<Exception>().RetryAsync();

Polly v7 gives async policies their own concrete base classes. These entirely eliminate the possibility of calling async execute overloads on sync policies (and vice versa). There are no changes for policies for synchronous executions.

Configuration overload Created, Polly to v6 Creates, from Polly v7
.Retry() RetryPolicy : Policy : ISyncPolicy RetryPolicy : Policy : ISyncPolicy
.Retry<TResult>() RetryPolicy<TResult> : Policy<TResult> : ISyncPolicy<TResult> RetryPolicy<TResult> : Policy<TResult> : ISyncPolicy<TResult>
.RetryAsync() RetryPolicy : Policy : IAsyncPolicy AsyncRetryPolicy : AsyncPolicy : IAsyncPolicy
.RetryAsync<TResult>() RetryPolicy<TResult> : Policy<TResult> : IAsyncPolicy<TResult> AsyncRetryPolicy<TResult> : AsyncPolicy<TResult> : IAsyncPolicy<TResult>

Retry is an example of the pattern, which applies to all policy types.

Why?

The change replaces a runtime exception with compile-time validation.

How to upgrade to v7

If you are already you are already referencing policies via the policy execution interfaces, no changes will be necessary.

There are no changes for synchronous policies.

If referencing async, non-generic policies via concrete base types

Code referencing a configured async policy via the v6 concrete base type will cause a compilation error in v7:

Policy retryPolicy = Policy.Handle<Exception>().RetryAsync(); // intentional compile-time error from v7

Replace the policy type either with the new, concrete async base type:

AsyncPolicy retryPolicy = Policy.Handle<Exception>().RetryAsync();

or the relevant execution interface:

IAsyncPolicy retryPolicy = Policy.Handle<Exception>().RetryAsync();

or var:

var retryPolicy = Policy.Handle<Exception>().RetryAsync();
If referencing async, generic policies via concrete base types

Similarly for generic policies, replace:

Policy<HttpResponseMessage> retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => /* some predicate on HttpResponseMessage */).RetryAsync(); // intentional compile-time error from v7

with:

AsyncPolicy<HttpResponseMessage> retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => /* etc */).RetryAsync();

or:

IAsyncPolicy<HttpResponseMessage> retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => /* etc */).RetryAsync();

or:

var retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => /* etc */).RetryAsync();

Allow cache policies to cache values of type TResult

What changed?

The core Polly cache policy code was changed so that it becomes possible to cache values of type default(TResult).

This necessitated changing the signatures of all methods in the following public interfaces:

  • ISyncCacheProvider
  • ISyncCacheProvider<TResult>
  • IAsyncCacheProvider
  • IAsyncCacheProvider<TResult>

Why?

Prior this change it was not possible to cache (for example) false of an execution returning a bool. See #523 for more detail.

How to upgrade to v7

If you are using cache providers supplied by the Polly team

Cache providers supplied by the Polly team have been updated to align with the changes. This covers:

Version of Polly Version of cache providers to use
up to V6 up to v2
v7 onwards v3 onwards
If you have implemented your own cache-providers

You will need to update for the changes to the cache provider interfaces shown here:

The changes required are small: to return a bool indicating whether an item was found in the cache, rather than using default(TResult) to signal that.

Dealing with diamond dependencies

Diamond dependencies can arise if you have a solution which references one version of Polly via one axis/in one project, and another project which references a different version of Polly, perhaps indirectly. This leads to a so-called diamond-dependency conflict, in which different code is built against different versions of Polly. Where those versions of Polly differ with breaking changes (eg between v6 and v7), this can cause compilation-time or run-time errors, as only one version of Polly.dll can be included in the built output.

To resolve this, ensure all projects reference the same (usually highest) version of Polly. Where a project references a lower version of Polly indirectly, place a reference to the higher version of Polly at the top-level of that project, and the indirect reference should switch to the higher version too, bringing all versions into line.

See this issue for a worked example with Polly v6 and v7, including visual examples of how the direct and indirect references should look.

These procedures work if you have entire control over the build (eg in your visual studio solution), but may not work if either:

  • you are referencing third-party nuget packages which have a reference to Polly v6 (and that package does not yet offer a version upgraded for Polly v7)
  • you are using one of the official ASPNET Core Docker Images
Clone this wiki locally