-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Only allow one of each links attribute in resolver #4978
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Awesome, thanks! It looks though like there's some CI failures? In addition to that, could some tests be added about successfully choosing a resolution when two possible graphs would have otherwise been possible? The final comment I'd have for this is is that resolution tends to be a pretty performance sensitive path in Cargo, so would it be possible to avoid the |
The CI failures are test looking for the old links checker, they will probably need to be updated. Maybe we should remove the old cheker entirely? That is a good suggestion for added test. As to performance:
|
We cant remove the old checker, |
@Eh2406 yeah I thin kit's fine to remove the old checker entirely. Although I will say though that the error messages from the old checker are quite good, and it'd be a shame to lose those... Fixing that may require a more general overhaul to resolver error messages which already aren't the best unfortunately :( In any case unfortunately I don't have many benchmarks for the resolver. The main one I've used in the past is "how long does it take to resolve Servo's dependency graph?" but without information in the index it'll be deceptively fast I think. In general though we just need to avoid allocations if possible on each turn of the loop if we can, or otherwise make sure the allocations are pretty small. Would it be possible to have a field that's updated over time rather than recreated each time? The allocations have been most of the runtime so far, I've never seen the hashing part of a hash map show up in profiles. |
The first time I tried this I had a persistent set, and got myself confused. Then I tried making the set dynamically and submit the pr. This time I got the persistent set to work. I think the third time's the charm! As to the old checker, I don't think we can remove it until we are sure that all of the index (and clones of the index) are updated to have the new field. I could be wrong, I am new to this codebase. If I am wrong, please enlighten me! Switching from the good old checker error messages to the resolver messages is a shame. But what can we do. :-( How hard is it to resolve Servo's dependency graph in isolation as someone that has never touched Servo's code befor? |
src/cargo/core/resolver/mod.rs
Outdated
@@ -1047,6 +1053,9 @@ impl<'a> Context<'a> { | |||
.or_insert(Vec::new()); | |||
if !prev.iter().any(|c| c == summary) { | |||
self.resolve_graph.push(GraphNode::Add(id.clone())); | |||
if let Some(link) = summary.links() { | |||
self.links.insert(link.to_owned()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this assert that we're not replacing somethign that was already there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could make it assert!(self.links.insert(link.to_owned()));
but I think this can get triggered if updating a lock file that already has multiple crates with the same links attribute. Is this acceptable? Is there some way to get better error messages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm that would indeed be bad! Thinking through how this can happen I think we could trigger this if an older cargo created a lock file with a bunch of new crates (that all have links
in the manifest) and then a newer cargo tries to use that lock file.
In that case, sounds like we should skip the assert for now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Er well, but if we do actually run into that case the previous project surely couldn't build previously becuase it would have been caught later...
How about this, could we return an error from here to entirely abort resolution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I have that working now.
Ok great! I think this looks good to me in terms of perf, and we can always continue to tweak as more cases come up. I've actually found it somewhat easy to profile with Servo before, but unfortunately it may not be too interesting to profile with this PR as-is (as there's no Otherwise I've historically just cd'd into Servos' checkout and run |
Oh right, some further thoughts:
|
So I got Servo set up so I can run the test. I benchmarked 4 versions. I am running windows so I don't have a
|
Thanks for investigating @Eh2406! I'm actually surprised it took 3 seconds at all, that sort of update should happen in milliseconds ather than seconds... Well in any case sounds like the current PR as-is is certainly acceptable speed-wise! |
I added the links attribute to the NewCrate struct then followed the error messages. Please let me know if I did that correctly. |
Ok thanks @Eh2406! Thinking about this some more... I'm getting more and more worried as I think about it about the error messages here. It's pretty well-known at this point I believe that the resolve error messages coming out of Cargo are pretty bad (almost un-actionable!). That's also coupled with the fact that non-resolvable crate graphs look like hangs I think could get us into a bit of a tight spot with this feature. For example we've, since inception, had requests and an implementation for better error messages around the In that sense I'm not entirely sure how to balance this implementation. On one hand I definitely believe it's technically correct (although would be good to have a test to assert that this error can guide crate graph resolution). On the other hand though I'm not sure that this is worth the loss in error message quality. From my experience cases like #4902 are coming up pretty rarely where there's a resolvable crate graph but Cargo isn't finding it immediately. I'm curious what you think about this as well? |
I have a lot to say in response to your comment. How much will actually be relevant to this pr I won't know till I try and say it. But I hope to do a lot of work on the resolver and it will be relevant to that larger context. I will try and respond point by point.
I agree! I would love to work on fixing them when I understand the resolver deeply so I can see how to improve it. I started working on this PR so I could begin to understand the resolver. If I begin with some low hanging problems, even if I never understand the resolver deeply I will still have contributed. I fear that making good error messages for resolver will be hard. Resolver currently returns some random crate it can not resolve, usually one that the user did not even know was being depend upon. It is not clear how to synthesize it into a larger coherent user centric message.
I think this is surprisingly tightly tied to the error messages. I think the solution to failing fast on most non-resolvable crate graphs in valves taking the fact that some random crate can not be resolved synthesize it into a larger coherent problem then back track until the bigger problem goes away. If we had a good way of building a larger coherent problem we would have them both solved.
I think all the cases that are debugabal in the current system, would just resolve into something that worked. I.E. If you can fix it by specifying a specific version of a dependency, then it will just no longer be an issue. The process of backtracking will find the dependency that works. Of course the resolver error messages are offil so if you have a bigger problem than pinning a dependency the error messages will get a lot worse.
I'd love some guidance on making a test in which cargo has multiple versions to choose from only the oldest of witch does not have a links attribute that conflicts with the main crate. Or any other test you would like to suggest.
I don't think that is an accurate description of #4902. I don't see that particular report mentioning cargo being slow. I see it reporting that cargo always builds a lock file that it then cannot use. With, in that case, no way to fix it. That is a really bad user experience. I think over all this replaces friendly error messages that clearly tell you what problem cargo made for you with cargo silently not making the error in the first place. |
I think this is a ergonomic win, but reasonable people can disagree. If you decide to postpone this until we somehow get better error messages then I will open up PRs related to other issues with the resolver and let this one bit rot. Knowing me, If I end up in a holding pattern I will likely get distracted, so one way or the other I'd like to keep things moving so I can contribute. |
Thanks for the writeup @Eh2406! (and sorry for taking a few days to get back to you) Mostly that all sounds great to me, I'd be thrilled to help you learn about the resolver if you'd like! One point though is...
Almost! A few days ago we talked about this more broadly in the cargo triage meeting and what to do with this PR. Our conclusion though was that we probably don't want to land this yet, but we're curious to learn more information! My fear, more specifically, is that entirely unresolvable crate graphs will start showing up (producing bad error messages). I suspect that, because we've improved the error messages here, it's somewhat often coming up in practice that there's multiple native libraries of the same name that can't get built together. While in #4902 it's possible that Cargo could have actually found a successful resolution I suspect that is not the case for most of the times this comes up in practice. Whenever I've seen this before it's been impossible to resolve the crate graph with this constraint, but rather a dependency simply needed to be updated. Along those lines though, @SergioBenitez as the reporter of #4902 is this an issue that's coming up in practice for you a lot? The solution in this PR will solve #4902 but will unfortunately create some other problems as well, so we're trying to figure out how to best weigh the priorities here. @Eh2406 if you'd like to tackle resolution one of the highest priority bits of it I think would be the error messages, and I'd be more than willing to help mentor you on improvements to that! |
Just a note for when someone/I come back to this, in addition to the error messages, It will take some work to rebase/merge this with #4834, and that is a much bigger/more common UX improvement. |
☔ The latest upstream changes (presumably #4834) made this pull request unmergeable. Please resolve the merge conflicts. |
# Conflicts: # src/cargo/core/resolver/mod.rs # tests/resolve.rs
Worked on the error messages, dose that look better? |
☔ The latest upstream changes (presumably #5063) made this pull request unmergeable. Please resolve the merge conflicts. |
📌 Commit 68a40ad has been approved by |
Only allow one of each links attribute in resolver This is a start on fixing the `links` part of #4902. It needs code that adds the links attribute to the index. But, I wanted to get feedback.
@Eh2406 also, would you be up for following through with the crates.io changes needed here as well? |
Um befor we merge, how do we test that adding |
☀️ Test successful - status-appveyor, status-travis |
@Eh2406 oh I'd be fine adding a test yeah, although I'm quite confident that it won't require any code changes. |
I don't think it's as simple as adding a test. Adding a test will test that it works with current cargo. I guess we would need to manually alter the index, and then every previous version of cargo. |
Ok so I am trying to test if the links attribute will brake old cargo. This is a log of my progress.
This test failed! In 2 ways:
TLDR: |
@Eh2406 IIRC Cargo at 1.0.0 actually unconditionally reads the registry, so you should be able to do:
For master cargo are you using nightly or building from source? I think these changes haven't made their way into nightly yet unfortunately. |
I think that is what I tried, but when Cargo 1.0.0 is For the master test I am building from source. |
Hm I'm not so sure in that case :(. Been awhile since I used Cargo 1.0.0... In any case using Cargo 1.20.0 or something like that (not too old) is probably sufficient. No one's using Rust 1.0.0 in production right now I'd imagine. As to why master isn't reading the attribute... not sure! |
made a clone of the index at https://github.com/Eh2406/crates.io-index. use .cargo/config to override. pushed https://github.com/Eh2406/crates.io-index/commit/2d969f4712c5aaa9083e5e964879b73c8ed59ae2 Good news:
Bad news: |
Good news I figured it out, and all is well! Switching to |
Nice! |
1248: Try to add links to the index r=carols10cents This is a companion to rust-lang/cargo#4978 It is adding the links attribute to the index git. I am working on windows so cannot test locally, I.E. this may involve some sparing with the CI to get this green. Advice and help are welcome!
This is a start on fixing the
links
part of #4902. It needs code that adds the links attribute to the index. But, I wanted to get feedback.