-
Notifications
You must be signed in to change notification settings - Fork 38
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
Use a VersionSet trait instead of Range #108
Conversation
In my Range trait branch I got it working some how, let me look. Here it is. |
Thanks, I will have a look at it! |
Question: Why do we require impl<L, R> RangeSet for EitherSet<L, R>
where
L: RangeSet,
R: RangeSet,
{
type VERSION = Either<L::VERSION, R::VERSION>; In resolve function, a BTreeSet of versions is used. let mut added_dependencies: Map<P, BTreeSet<V>> This one does not seem like is needed. It seems it is only used to check if we have already added dependencies of a given package to the solver incompatibilities. That could be replaced by a hash map, to require The OfflineDependencyProvider uses the order in a BTreeMap: pub struct OfflineDependencyProvider<P: Package, VS: VersionSet> {
dependencies: Map<P, BTreeMap<VS::V, DependencyConstraints<P, VS>>>,
} Since this is only an implementation, we could add the Side remark. It could also make sense to implement RangeSet/VersionSet (same thing, different branches) for the same type on each dimension: Anyway, a lot of food for thought. |
Thanks, that's what I was looking for, what a mouthful ^^ https://github.com/pubgrub-rs/pubgrub/blob/range-trait/src/solver.rs#L306-L314 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(bound(
serialize = "R::VERSION: serde::Serialize, R: serde::Serialize, P: serde::Serialize",
deserialize = "R::VERSION: serde::Deserialize<'de>, R: serde::Deserialize<'de>, P: serde::Deserialize<'de>"
)))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct OfflineDependencyProvider<P: Package, R: RangeSet> {
dependencies: Map<P, BTreeMap<R::VERSION, DependencyConstraints<P, R>>>,
} |
To check if we have already added the dependencies. A hashmap would work just as well, but was not compatible with the
The provided types will have some set of behaviors, probably:
If a user does not want that behavure, they can change the |
Indeed. Since we are changing the API, it seems more appropriate to me to ask for Now for the rest of this PR, I'd like to try the following (making a todo list for me to remember):
|
Also we should look into the |
When I remove the bound, there are compiler errors for
We could probably format the unreachable in Here is one of the errors: /// Error arising when the implementer of
/// [DependencyProvider](crate::solver::DependencyProvider)
/// returned an error in the method
/// [get_dependencies](crate::solver::DependencyProvider::get_dependencies).
#[error("Retrieving dependencies of {package} {version} failed")]
ErrorRetrievingDependencies {
/// Package whose dependencies we want.
package: P,
/// Version of the package for which we want the dependencies.
version: VS::V,
/// Error raised by the implementer of
/// [DependencyProvider](crate::solver::DependencyProvider).
source: Box<dyn std::error::Error>,
}, |
|
Logging and errors seams like enough resin to keep it. Thanks for the investigation! |
Is the checklist mentioned earlier in the thread still up to date ? I'd be happy to do some of the work required to help get this merged |
@raftario indeed, this is still relevant! Don't hesitate to try a few things if you are interested in investigating this. You might want to have a look at some conv in this zulip chanel for more context on that issue and checklist: https://rust-lang.zulipchat.com/#narrow/stream/260232-t-cargo.2FPubGrub/topic/pre-releases A few remarks though, we want to proceed with cautious with this one and #104 since those are the two with the most flexibility and performance benefits but at the price of API changes. I've personally had a very busy time at work so could not spend much time on pubgrub. Plus we are currently preparing for Packaging Con where we'll be presenting this work in a few weeks :) |
I made a This can be extended from |
Hi! I was wondering what the status of this PR is. I'm trying to use Pubgrup to resolve package constraints in a conda environment. Dependency constraints in conda can become quite complex through the matchspec format. A package can be queried not only by version but also by a lot of other constraints like its md5 hash or filename. Most commonly though it's a version specifier (or a combination of version specifiers) (e.g. I've started working on this in public repository here where for now I only support version specifiers, but I've been running into numerous crashes in pubgrub, especially this one:
on this location: pubgrub/src/internal/partial_solution.rs Line 302 in 7727938
and this one:
on this location: pubgrub/src/internal/partial_solution.rs Line 130 in 7727938
I'm not sure if it's my code or that this PR simply isn't done yet. Any help would be greatly appreciated! I would be happy to jump on a chat or video call too! |
Hi @baszalmstra thanks for the feedback! Regarding the crashes, are they happening with this specific branch or with the normal release? From feedback we've had from other people having crashes, in the normal case it turned out that crashes always happened because they did not strictly follow the requirements of the version traits (about order). But maybe this is something new. If that's new, I hope we can figure it out. Regarding the state of this PR, it's in pause right now. I'm finishing my current work contract in a month from now, and since last year, end of 2021 I've been too busy to continue here and continue reviewing Jacob's commits. My plan is to take some time off between the end of my contract and a new contract so that I can spend a bit of time on my OSS projects, and here in particular! I hope it's not too much of a blocker for you and you are able to get things done otherwise. That's also why we wanted to have a solid version 0.2 release with clearly stated limitations in the docs. |
Hey @mpizenberg! I get that, OSS works does take a significant amount of time! I really appreciate all the work you and the others put into this already! I'm running the It is kind of a blocker right now unfortunately, you wouldn't have any other tips on debugging these issues? |
You pointed me in the right direction, I just implemented exactly that. I have a constraint that represents a DNF of structs that contains multiple constraints. The complement is then easily computed as well as the intersection, see: https://github.com/baszalmstra/rattler/blob/main/crates/rattler/src/match_spec_constraints.rs . I just implemented two simple constraints ( I haven't encountered any crashes anymore but I did run into the problem that for some queries the solver goes into an infinite loop. I find it a bit hard to read the code. Would you have an idea why this could happen? You can try out my code from: https://github.com/baszalmstra/rattler Its very experimental currently but you can run it with: Any help would be greatly appreciated! |
When we get this working right, an example should definitely be in this repo. |
It does reliably reproduce the infinite loop. Im sure there is still a bug somewhere in my code too, but I find it very hard to find. Would it be possible to add some logging to the solver to be able to make debugging easier? |
So it is stuck in this loop https://github.com/baszalmstra/rattler/blob/main/crates/rattler/src/match_spec_constraints.rs#L143-L149 on an input where There has to be a non exponential way to combine these, but I have not thought of it yet. |
Ah crap that was my fear. And that will obviously become worse if I add more constraints to it. Im going to think about this some more too. Hopefully, we can figure something out.. |
Mm I "optimized" the |
Caching can only solve the problem of a function being called too often. In this case the problem is that a single call takes too long. Putting a print before and after: https://github.com/baszalmstra/rattler/blob/main/crates/rattler/src/match_spec_constraints.rs#L123-L131 However I am now seeing the stuck outer loop you reported. I do not have time to investigate now. Guessing we are going to find another property related to how we test for subsets. |
I did some more investigation but don't have a lot to show for it. |
@Eh2406 Ill try to create something like that! |
I've started creating a smaller test case. I've also created a PR to get my |
Sorry for the long time without activity. I'm getting some attention back to this so that we can progress towards v0.3. I'm going to recap what happened here, with additional context from other discussions, so that we know where we are, and what we can do to move forward. Changes in this PRThe goal here is to give more flexibility to implementors of dependency providers, by defining a trait /// Trait describing sets of versions.
pub trait VersionSet: Debug + Display + Clone + Eq {
/// Version type associated with the sets manipulated.
type V: Debug + Display + Clone + Ord;
// Constructors: empty(), singleton(Self::V)
// Operations: complement(&self), intersection(&self, &Self)
// Membership: contains(&self, &Self::V)
// Automatically implemented functions ###################
// Constructor: full()
// Operations: union(&self, &Self)
} One key difference is that the associate type Questions and current choicesThis change brings many questions on the current design decisions.
(1) The (2) The (3) It is important to provide at least one implementation of the The For these reasons, ergonomics + unknowns, in addition to the fact that this is something that could still be implemented later in a minor release, it makes more sense to not consider implementations of generic Now regarding the continuous, bounded interval trait implementation, my feeling is that we do not need to replace the current Other small remarksWe should probably rename the We will also need an "Upgrade from v0.2 to v0.3" section in the guide, as well as an explanation for how to update RON files from the old to the new types. Finally, we'll need a guide section on "How to test my dependency provider implementation?" for people implementing their own We may also want to reconsider the "interior mutability" pattern we are imposing on users due to not using SummaryI hope I have not forgotten important info or made big mistakes, don't hesitate to correct me if that's the case or to voice your concerns if you don't agree with some of my points. So I propose we move forward as follows, let me know what you think.
Many of the above points can be done in parallel after this PR is merged (1). And after publishing v0.3 we can refocus on the nice-to-have and new code. In no particular order:
|
First off, thank you for the summary! You said a lot of really valuable stuff. For the sake of brevity I am not going to mention all the times I agree with what you said. I think the decision about how much this repo shuld support continuous ranges, can better be had in a separate thread. This conversation is already very long. Let's merge this PR and open separate issues for each of the points you brought up! (And all the other valuable conversations that have happened in this thread, like |
Thanks for the detailed summary @mpizenberg! Getting this MR merged sounds great! :) |
@Eh2406 did you forget to check the required review to be able to merge this PR or are you planning on doing it later? |
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 forgot what the ceremony was in this repo. Sorry.
No worry, yeah we still have 1 review requirement before merging stuff. |
* refactor: introduce a trait for sets of versions * refactor: port report and incompatibility to version set * refactor: port errors to version set * refactor: port partial solution to version set * refactor: move DependencyConstraints to type_aliases * refactor: port core to version set * refactor: port solver to version set * refactor: replace old modules with ones based on version_set * refactor: update tests to version_set * feat: add serde bounds to OfflineDependencyProvider * refactor: update proptest.rs to VersionSet * docs: fix links * refactor: allow clippy type_complexity * Small docs changes
In this PR, we have now
Range
as an implementation of the newly introducedVersionSet
trait, defined as follows:Compilation and tests are passing while deactivating the
serde
feature. I wonder how to properly write the fact thatVersionSet
and itsV
associate type must be serializable when we have theserde
feature so thatOfflineDependencyProvider
can be serializable.