Skip to content

fix: deadlock for duplicate packages from different sources#5447

Merged
Hofer-Julian merged 7 commits intoprefix-dev:mainfrom
baszalmstra:fix-lucas-issue
Feb 11, 2026
Merged

fix: deadlock for duplicate packages from different sources#5447
Hofer-Julian merged 7 commits intoprefix-dev:mainfrom
baszalmstra:fix-lucas-issue

Conversation

@baszalmstra
Copy link
Contributor

Description

Fixes an issue where two source builds of the same package but from different locations would deadlock. This PR ensures that caches are appropriately seperated.

This also removes the git reference from caches (using CanonicalSourceLocation), because only the commit really matters.

How Has This Been Tested?

Tested using a reproducer from @lucascolley

AI Disclosure

  • This PR contains AI-generated content.
    • I have tested any AI-generated content in my PR.
    • I take responsibility for any AI-generated content in my PR.

Tools: Claude Code Opus 4.5

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added sufficient tests to cover my changes.
  • I have verified that changes that would impact the JSON schema have been made in schema/model.py.

@lucascolley lucascolley added bug Something isn't working area:build Related to pixi build labels Feb 5, 2026
@baszalmstra baszalmstra requested a review from tdejager February 6, 2026 08:18
@baszalmstra baszalmstra added the test:extra_slow Run the extra slow tests label Feb 6, 2026
) -> String {
match manifest_source {
CanonicalSourceLocation::Url(url) => {
let mut hasher = Xxh3::new();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make this a method on CanonicalSourceLocation?

I think it will be a nice API

CanonicalSourceLocation::unique_key(something, source)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestions, moved to CanonicalSourceCodeLocation::cache_unique_key

// Check the source metadata cache, short circuit if there is a cache hit that
// is still fresh.
let cache_key = self.cache_shard();
let cache_key = BuildBackendMetadataCacheShard {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we adjust self.cache_shard() or make separate function for it?

self.manifest_cache_shard?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It requires input from the current function and we dont need it anywhere else. So Im inclined to leave as is.

/// resolved location is not.
pub build_source: PinnedSourceSpec,
///
/// If this field is none, its the same as the `manifest_source`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok now I'm getting really curios here!

Could we somehow express it with a separate type? So I dont need to manifest_source != build_source in order to know if I have a build_source or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a type and used it everywhere!

// Get the skip_cache flag from the build backend metadata
let skip_cache = build_backend_metadata.skip_cache;

let shard = SourceMetadataCacheShard {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a method for it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Id like to keep it here because it uses local variables.

}

let records: Vec<SourceRecord> = futures.try_collect().await?;
let records: Vec<_> = futures.try_collect().await?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need typing Vec here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes otherwise in the line below we do not know how to resolve records.is_empty

@baszalmstra baszalmstra requested a review from nichmor February 10, 2026 09:29
@baszalmstra
Copy link
Contributor Author

@nichmor Ready for another review!

@ruben-arts ruben-arts enabled auto-merge (squash) February 11, 2026 09:47
@Hofer-Julian Hofer-Julian merged commit c4e66ef into prefix-dev:main Feb 11, 2026
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:build Related to pixi build bug Something isn't working test:extra_slow Run the extra slow tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants