dotnet / orleans

Cloud Native application framework for .NET
https://docs.microsoft.com/dotnet/orleans
MIT License
10.07k stars 2.03k forks source link

Nuget Package Usage Rules.md #1327

Closed attilah closed 8 years ago

attilah commented 8 years ago

This is a discussion starter about Nuget package usage rules.

We've to define that -1 rule and then keep it that way with every release.

In the semver age it is hard to define the version dependency.

It is possible that we'll have exceptions because of a given reason (like a blocking know bug or framework requirement or any other thing), so we've to keep that rules.md file updated to make every developer aware of our decisions about the rules.

-1 rule can be: A. -1 Major version B. -1 Minor version C. -1 Stable release on nuget

Since nuget has no votes...it will be hard to collect the +1 for the possible votes.

Let's discuss!

attilah commented 8 years ago

My +1 is for "C"

jthelin commented 8 years ago

A clarifying question @attilah -- Let's say we consider the Azure SDK [which is one of the worst citizens of version-land IMHO, but quite illustrative of the problem area ;) ].

Current version is 2.8.1 according to Azure home page, although "release note" have not been updated and still refer to 2.8 https://azure.microsoft.com/en-us/develop/net/ https://azure.microsoft.com/en-us/blog/announcing-the-azure-sdk-2-8-for-net/

I would say N-1 principle should mean 2.7.x or 2.8.x, which i think equates to option "B" above?

Specifically, i do NOT think N-1 should mean just 2.8.0 + 2.8.1, which was how i interpreted option "C"?

BTW, Azure SDK is a slightly contrived example due to the weird "ServiceRuntime" component which is hard versioned but not NuGet, so please use the example above just as an example :)

Thoughts?

attilah commented 8 years ago

Azure SDK can be one of the exceptions where we have to stick to SDK versions or SDK-1 versions meanwhile it does not matter what is the version of the azure nuget packages.

I'm sure you meant 2.8.1 + 2.8.2 ;-)

https://azure.microsoft.com/en-us/blog/announcing-azure-sdk-2-8-2-for-net/

sergeybykov commented 8 years ago

Azure is a special case, but we don't care as much about it anymore after we wrapped ServiceRuntime into a Reflection-based wrapper. Azure Storage seems like an almost separate story even though it ships with the SDK.

Thinking in general, the moment we are not on the latest version of the dependency NuGets, I don't think it make a big difference if we are -1 from major or minor or even -2. If somebody needs to use a more recent version of a dependency, it's the same amount of [unfortunate] work regardless of how behind we are.

On the flip side, if we are too aggressive in taking dependency on a newer version of a dependency, we impose potentially more work on consumers of our NuGets even if don't actually need any functionality from the newer version.

So it seems to me that it's better for us to stay more conservative with moving to new versions unless there is a real functional need or a bug/issue (like we found with Azure Storage 5.0). In that light, I think we should choose between A and B. Am I missing any benefits of C?

jdom commented 8 years ago

Piggybacking on @sergeybykov's comment, I do not think we should be updating the dependencies just to always be -1 on the latest (whether it's major, minor or whatnot). We should only upgrade if there is an actual need in Orleans for those new features in the dependencies. The -1 should be the max version we should be able to move to in those cases that we need to. Having said that, we should try to make sure that our usage of that dependency is forward compat with the latest version, so if someone in their own app is using the latest of that other package, then using binding redirects is good enough. Typically this is easy, as Orleans being a framework tends to not use all the nitty gritty APIs from that dependency and thus when it changes, using binding redirects just works. An example of explicitly being forward compat while not necessarily updating to the latest is #1024. The reason of not always being on the latest (or ALWAYS on latest-1 whether we require it or not) is important is that if we were, we are always forcing everyone to update their own apps when we fix stuff in Orleans (which typically is more critical to users than a Json.NET upgrade). And for them, where they might be using the library more extensively or with less care, a binding redirect might not cut it (or might fail silently which is worse), and they might be forced to doing tough upgrades unnecessarily, or decide to not take the Orleans upgrade entirely. On the other hand, if we are on latest-1 (whatever that option means), then if an app developer cares to always be on the latest regardless, it would be the same effort in terms of binding redirects (that are "solved" by NuGet) as if we were on version X (where X is not necessarily latest-1, just the latest that we needed for a certain feature in Orleans). Having said all that, I would vote that the latest we can upgrade to when we do need it is option A (-1 major version), assuming they follow semVer. But this should not be extremely strict and should be treated on a case by case. For example, if a library has been stable in the latest version for a very long time, it should be fine to upgrade to that latest, but only if we so require, or if there is no way we can't be forward compat when referencing the previous version.