-
Notifications
You must be signed in to change notification settings - Fork 1.1k
dotnet store cross-gen all versions of a dependency #1211
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
Comments
Store command has not inherent knowledge of which package will be required at runtime and should not be in the business of determining that as well. The only entity who knows this is the store profile manifest author who generates the store and they should use such knowledge to figure out what should be present or not. |
The store command creates the fully expanded graph of dependencies for the packages you specify. There is no dependency version unification between separately specified packages. The reasoning is because if someone just references |
We are not concerned about the scenario of users referencing the |
Why do you refer M.A.Hosting 1.0 ever in M.Application.AspNetCore:2.0.0. Should you not be removing the reference there. From the store user's perspective the App actually might not want to use M.A.Hosting 2.0 and actually downgrade it to some other version of M.A.Hosting that is the lowest common denominator. |
We don't ship M.ApplicationInsights.AspNetCore. That's created by the AppInsights team and they depend on our LTS 1.0.0 versions. However, in our store we would prefer hoisting up to the latest versions of our packages. If the user would like to downgrade then they will just end up with the older versions of our packages in the app local output. My understanding is that stores are composable. If you want to, you can install the 1.0.0 store (hypothetically, but we won't be building it) and the 2.0.0 store and trim by the manifest of both. Otherwise the 2.0.0 store should only contain 2.0.0 packages and any 1.0.0 packages will be published app-local. |
This is the shortcoming of how the packages are specified, if we are to take a unit of dependency then nuget will compute the correct package graph. From the generic store functionality we have two options:
|
By 3, I mean We will have to take a breaking change to ensure that the ItemGroup names are consistent with their other usag |
@JunTaoLuo Why do we think this is required for 2.0? Store command's granularity is package and based upon the transitive closure of the packages specified. |
An optional workaround here for 2.0 is to create a single package that references all the packages you want in the store. Then specify that single package in your manifest. The store command will only create 1 package graph for the whole store instead of restoring each package individually. |
I'll give that a try. |
dotnet store is basically on life support right now. I'm trying to simplify it as I fix what's been broken during recent changes and to prevent it from being such a high tax on future changes. It looks like it would be drastically simpler to do option 1 above:
@eerhardt @DamianEdwards @jeffschwMSFT @fadimounir Any objections to this breaking change? The result will be that what is stored is based on the normal nuget rules for a set of package references in a project file. If you want to store multiple versions, you will need to put use more than one file / dotnet store run. |
Are we certain we need to fix this issue? I don't think ASP.NET uses the |
I think we still use dotnet store in our 2.x servicing for building site extensions, is that right @natemcmaster @dougbu? |
For that, you would use a 2.x sdk, though, right, so it would not be impacted by this. The change I'm proposing would impact 3.0 sdk and onward. |
Oh okay, yes I think that should be okay then. |
We still use |
@natemcmaster Thanks for noting that. Does the change I proposed above work for that? |
@normj Reaching out to you as a user of dotnet store based on https://github.com/dotnet/cli/issues/10784 Would the proposed change above work for you? Basically, if there is "incoherence" in the list of packages to store, then they would resolve in the usual nuget way for a single project. For example, if we're asked to store: A v1 And dependencies are: A v1 -> B v1 -> C v1 Then we will store A v1, B v2, C v2 under the proposal: Whereas before we would store A v1, B v1, C v1, B v2, C v2 If you really wanted to store multiple versions of packages, you would have to run store multiple times with different inputs. |
I think the proposal works for aspnet. I review the store we ship in Microsoft.AspNetCore.AzureAppServices.SiteExtension, and I only see one version of each package. |
For reference here is a description of how we use dotnet store at AWS for use with Lambda functions which is AWS's serverless technology. https://aws.amazon.com/blogs/developer/aws-lambda-layers-with-net-core/ The short answer is yes this would be a breaking change that could negatively impact our users. The intention is users will create a package store and then reference that for any number of Lambda functions they want to deploy. Those Lambda functions can use a variety of versions of the dependencies. Usually what I tell users who have a collection of functions is create a separate store manifest taking all of the packagereferences in their projects and create a store from that which will get all of the separate versions. With this change that workflow isn't guaranteed to work anymore. Since our users are using the store to create prejitted versions of the dependencies some Lambda functions that are using a different version then the resolved dependency in the store their performance will suffer as they silently stop using the prejitted version. Keep in mind our users don't directly work with the store. Our tooling abstracts the store away. Thanks @nguerrera for tagging me on the issue. |
Thanks, @normj
What determines the version of the .NET Core SDK that use used to create the store artifacts?
I'm asking above because it doesn't quite feel silent if there's some step to switch to 3.0 and generate a new store, where this could be documented. The current behavior make the implementation quite complex and has caused quite a few issues: Do you have a sense for how common it is to have a store in your system with multiple versions of the same package? |
We don't do anything special for choosing the SDK. We use the Silent might not have been the right word. By silent I mean the user created in our case a Lambda layer which for .NET is a package store and expected all of their dependencies to be put in the store including multiple versions of the same assemblies. When the Lambda function is packaged our tooling calls the They will see during the deployment the list of files being added to the package bundle so again silent was probably not the right word. That is assuming deployment is an interactive deployment and not a CI/CD deployment. A switch when running Sadly I don't have a sense of how common this is. The biggest benefit for the features is the prejitting since it dramatically cuts down cold starts. In those scenarios the proposal is completely fine. I don't want to sound like I'm trying to hold changes back. I prefer you guys being able to push forward and clean things up and make things work great. What I need to understand is if you implement this change and a user does find themselves in the case of needing multiple versions in the package store what is the workaround to make that happen. |
This would be great to have, unfortunately I don't know how to implement it in the planned simpler implementation I have in mind. Basically, I'd like to treat the manifest like any other project and stop doing heroics to restore each package in isolation. I don't think nuget returns us enough data to know what the delta is between every package's individual graph and the resolved graph is. cc @nkolev92
At a lower level, the workaround would be to specify the other versions in a different manifest and run dotnet store multiple times. Could you support multiple manifests per "layer"? |
Another workaround would be to add direct references where appropriate to lift things up to the version in your store. Another thing you could do, I think, is to have all your projects have a project reference to your manifest project and not have individual package references to the things in the store. Instead let come transitively. It makes the manifest project like a meta package. The downside is that you're over-referencing things individual projects don't need, but that shouldn't be a big deal since the extra files will still be excluded from your publish output. |
Another idea would be to warn on publish that we are deploying Foo vX as only vY is in the store. That is much easier to implement and I think it's less noisy. |
Are you saying If |
Late response here, but that's correct, there's not enough data for that. Only the information for the selected packages will be contained in the assets file, so you could only recreate the overlapping parts of the graph. |
Any progress on this issue? |
Yes, I have a pr up that should get merged tomorrow. It should fix the race conditions and allow tfm of 3.0 with store. But it's not the redesign I envisioned above nor does it change anything about storing multiple versions. I still hope to get that in, but it's quite big and I don't have an ETA. I believe nothing is blocked on it after the current pr goes in. |
I was curious because it might help with dotnet/aspnetcore#11186 which we will need for preview7. I'm not yet sure if this issue will block that but my hunch is that it shouldn't. |
Removing template changes from the 2.0.0 servicing branch. This reverts commit 32b9c32.
Removing template changes from the 2.0.0 servicing branch. This reverts commit 8e0419d.
From my understanding, the current dotnet store restores and cross-gens each package separately and this could lead to multiple versions of the same dependency in the store, even though we envision only one version being loaded at runtime.
This is better illustrated by the Microsoft.AspNetCore.Hosting package in the sample repro I have created at https://github.com/JunTaoLuo/StoreMultiVersion. The dependency is brought in via
Microsoft.ApplicationInsights.AspNetCore:2.0.0 -> Microsoft.AspNetCore.Hosting:1.0.0
andMicrosoft.AspNetCore.Server.Kestrel:2.0.0-preview1-final -> "Microsoft.AspNetCore.Hosting:2.0.0-preview1-final
. This leads to both the 1.0.0 and 2.0.0-preview1-final versions of Hosting to be produced in the cache in the .out/ directory of the repro.We envision users to consume all of our packages through the metapackage which means the version of Hosting will always resolve to 2.0.0-preview1-final, see the obj/project.assets.json and the *.deps.json files. The proposal here is that since only the 2.0.0-preview1-final version is used by the app, we should only produce stores with that resolved version by mimicking the logic in restore. Does this make sense?
cc @gkhanna79 @eerhardt @ramarag
The text was updated successfully, but these errors were encountered: