Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[expected diamond-dependencies problem: breaking change between v6 and v7] Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' #592

Closed
mrmartan opened this issue Feb 18, 2019 · 9 comments

Comments

@mrmartan
Copy link

mrmartan commented Feb 18, 2019

Summary:

I have updated from Polly 6.1.2 to the latest version (7.0.2) and I am not able to us it in conjunction with latest Microsoft.Extensions.Http.Polly (2.2.0, or probably any but that's the one am using). I have not tried 7.0.0 or 7.0.1

My target is netcoreapp2.2

Expected behavior:

No exception thrown

Actual behaviour:

TypeLoadException thrown
Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' from assembly 'Polly, Version=7.0.0.0, Culture=neutral, PublicKeyToken=c8a3ffc3f8f825cc'.
at Microsoft.Extensions.DependencyInjection.PollyHttpClientBuilderExtensions.AddTransientHttpErrorPolicy(IHttpClientBuilder builder, Func`2 configurePolicy)

Steps / Code to reproduce the problem:

Use PollyHttpClientBuilderExtensions.AddTransientHttpErrorPolicy with Polly 7.0.2

public static IHttpClientBuilder AddStandardTransientHttpErrorPolicy(
    this IHttpClientBuilder builder)
{
    if (builder == null)
    {
        throw new ArgumentNullException(nameof(builder));
    }

    return builder.AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.CircuitBreakerAsync(
            handledEventsAllowedBeforeBreaking: 2,
            durationOfBreak: TimeSpan.FromMinutes(1)));
}
@reisenberger
Copy link
Member

reisenberger commented Feb 18, 2019

@mrmartan It sounds like a classic diamond-dependencies problem. It sounds like your main project references Polly v7.0.2, but via Microsoft.Extensions.Http.Polly you still have a reference somehow to Polly v6.1.2.

Edit: Or possibly you have one project in a solution referencing Polly v7, another project referencing v6.

This isn't something we need to (or can) fix by changing Polly, afaiu. You just need I think to get all the references from your projects to Polly to match, so that none reference different major versions via different ('diamond') routes. The nuget tooling should get the references to Polly right for you, so that these problems do not occur.

Suggest:

  • Manually check all the references to the Polly nuget package in your app, eg in the raw .csproj files or in packages.config (if using that). Check all references to Polly say v7.x, none say v6.x still.
  • and/or completely Clean the build (Build->Clean within visual studio, or delete existing build output folders), so that you have no copies of an older Polly.dll cached in the build
  • and/or Uninstall and re-install the relevant nuget components.

To show what I mean, I created a .NET Core 2.2 Console App and first installed Microsoft.Extensions.Http. Nuget references for the project then shows this:

image

Then I manually install Polly v7.0.2 into the same project. The nuget tooling in Visual Studio automatically sorted out the indirect reference to Polly via Microsoft.Extensions.Http.Polly so that there was no mismatch in the diamond dependencies - see below:

image

This ^ is the state you want to get to.

I was then able to take exactly your extension method above AddStandardTransientHttpErrorPolicy() and configure an http client with it, compile and run.

Hope this helps.


If you think there is still something wrong, please provide an exact sequence of steps to reproduce - or a minimum verifiable example eg as a ZIP download.

@reisenberger reisenberger changed the title Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' [diamond-dependencies nuget install problem] Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' Feb 18, 2019
@reisenberger
Copy link
Member

@mrmartan Also, reading again the precise exception message:

Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' from assembly 'Polly, Version=7.0.0.0, Culture=neutral, PublicKeyToken=c8a3ffc3f8f825cc'.
at Microsoft.Extensions.DependencyInjection.PollyHttpClientBuilderExtensions.AddTransientHttpErrorPolicy(IHttpClientBuilder builder, Func`2 configurePolicy)

Polly.CircuitBreakerTResultSyntaxAsync is a Polly v6.x only class. And the exception message says it is trying to find it in Polly v7.0.0. This suggests that your app build has placed the Polly v7 dll in the output folder, but that some other dll/other binary has not rebuilt - that other binary is still built as if it thinks it is referencing Polly v6.

Again, I would suggest entirely cleaning all build output folders and re-building the app. If that fails, uninstall and reinstall relevant nuget components (... but this should not be necessary if the app build can be completely cleaned).

I have tried again to re-create the issue by uninstalling and re-installing / upgrading and downgrading each of the nuget components in various sequences, but could not reproduce the issue.

@reisenberger reisenberger changed the title [diamond-dependencies nuget install problem] Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' [diamond-dependencies nuget/build problem?] Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' Feb 19, 2019
@reisenberger
Copy link
Member

@mrmartan Did you get this resolved?

@AceHack
Copy link

AceHack commented Mar 19, 2019

I'm having the same issue and it's not resolved by the steps above

@AceHack
Copy link

AceHack commented Mar 19, 2019

As far as I can tell there is some breaking change between 6.x and 7.x and Microsoft.Extensions.Http.Polly v2.1.1 still references 6.x so it's impossible to upgrade to 7.x and have it work if using Circuit Breaker setup in DI.

@reisenberger
Copy link
Member

Hi @AceHack . Please post example code of what is not working for you - we are keen to see it and help further.

Because of what did and didn't change between Polly v6 and v7 - and exactly which parts of the Polly codebase Microsoft.Extensions.Http.Polly references - I would expect the above steps to work, but obviously keen to see if you have a non-cooperating case.

See also the longer discussion in #615. @altso identified rightly that if the reference to v6 is built into some nuget package (which you can't control to update to v7), then yes, you could have an unresolveable v6/v7 diamond-dependencies conflict. (That is the nature of diamond-dependency conflict if some third-party library doesn't update.) .

@reisenberger
Copy link
Member

@mrmartan @AceHack I am still curious to get to the bottom of what could be the problem in your examples - so as to help.

I went back to the fix I had previously tried for @mrmartan 's example: it is attached here: Issue592-20190218example-solved.zip. This compiles and runs fine in my environment. Does it for you? What might be different about your examples?

When we designed the Polly extensions to HttpClientFactory, we put together various overloads, some of which take an already-created Policy instance, some of which provide a policySelector func which will be used to resolve the policy at runtime. I was curious to re-check if there was any difference between early-resolved and late-resolved policies. But all available overloads (as just linked) work in my zip example.

Can you provide any more details - or example code - for the cases where you are experiencing difficulty?

@mrmartan
Copy link
Author

mrmartan commented Mar 21, 2019

@reisenberger's reasoning seems sound. I was not able to try/confirm his results though. In the meantime I downgraded to Polly v6.

It could be related to nuget/build process. My setup in detail:

App (Microsoft.AspNetCore.App, Polly v7) --> MyNuget.Library (Microsoft.Extensions.Http.Polly 2.2.0)

Microsoft.AspNetCore.App version is picked up from the runtime, in effect the dotnet:2.2.1-aspnetcore-runtime docker image

@reisenberger
Copy link
Member

Right. If the docker image dotnet:2.2.1-aspnetcore-runtime has a hard reference to Polly v6 baked in somewhere it, then yes, you might not be able to get away from the diamond dependency conflict.

@AceHack Can we help any further with your case?


Two bigger picture observations worth keeping in mind (for anyone coming to this discussion later):

  • ASPNET Core 3.0 plans to reference Polly v7 (issue title behind that link wrong btw ... conclusion correct!). So, soon, ASPNET Core and Polly will be back in sync ...
  • You are not missing a huge amount if you still have to be on Polly v6 with .NET Core 2.2. Polly v7 cleaned up some sync-async split (but no actual functionality changes - just cleaner usage). And fixed one bug around caching default(TResult) for cache policies. Details here: https://github.com/App-vNext/Polly/wiki/Polly-v7-breaking-changes .

Generally, we avoid breaking changes (major-version bumps) as much as possible in Polly - as the history shows - we actually held back the caching fixes from release earlier, to make a co-ordinated single bump at v7. But sometimes progress isn't possible without it.

@reisenberger reisenberger changed the title [diamond-dependencies nuget/build problem?] Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' [expected diamond-dependencies problem: breaking change between v6 and v7] Could not load type 'Polly.CircuitBreakerTResultSyntaxAsync' Mar 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants