Skip to content

Conversation

@oconnor663
Copy link
Contributor

Fixes #13703.

If I repeat the repro steps from my comment on that issue with this PR, the errors are gone:

$ cat >setup.py <<EOF
import setuptools
setuptools.setup(name="scratch", version="4")
EOF
$ for i in `seq 10` ; do
    ~/uv/target/fast-build/uv build --wheel &
done
[...lots of build output, no errors...]

There's also no performance impact:

$ hyperfine "/tmp/before build --wheel" "/tmp/after build --wheel"
Benchmark 1: /tmp/before build --wheel
  Time (mean ± σ):     255.8 ms ±   3.0 ms    [User: 225.7 ms, System: 41.5 ms]
  Range (min … max):   251.4 ms … 260.5 ms    11 runs

Benchmark 2: /tmp/after build --wheel
  Time (mean ± σ):     255.3 ms ±   2.6 ms    [User: 219.7 ms, System: 47.3 ms]
  Range (min … max):   252.8 ms … 262.0 ms    11 runs

Summary
  /tmp/after build --wheel ran
    1.00 ± 0.02 times faster than /tmp/before build --wheel

@oconnor663 oconnor663 requested review from konstin and zanieb June 20, 2025 23:30
@oconnor663 oconnor663 temporarily deployed to uv-test-registries June 20, 2025 23:32 — with GitHub Actions Inactive
@charliermarsh
Copy link
Member

I don't think locking the output directory is actually sufficient because IIRC setuptools uses a build directory in the source directory? So, like, concurrent builds to different output directories would still fail?

@oconnor663
Copy link
Contributor Author

oconnor663 commented Jun 21, 2025

Ah true, I still get failures with something like this:

$ for i in `seq 10` ; do
    ~/uv/target/fast-build/uv build --wheel --out-dir /tmp/mybuild$i &
done

@oconnor663 oconnor663 force-pushed the jack/lock_wheel_builds branch from e4a8f29 to 0019a4a Compare June 23, 2025 21:47
@oconnor663 oconnor663 temporarily deployed to uv-test-registries June 23, 2025 21:49 — with GitHub Actions Inactive
@oconnor663
Copy link
Contributor Author

I've switched to locking (the hash of) the source dir. The following now succeeds with no errors, and the builds run in series:

$ cat >setup.py <<EOF
import setuptools
setuptools.setup(name="scratch", version="4")
EOF
$ for i in `seq 10` ; do
    ~/uv/target/fast-build/uv build --wheel --out-dir `mktemp -d` &
done

I'm considering refactoring this a bit to stop putting so many file locks directly in /tmp. Going to put another PR on top of this one, which we can take or not.

@oconnor663 oconnor663 changed the title Make uv build lock its output dir, to prevent concurrent builds from interfering Make uv build lock its source dir, to prevent concurrent builds from interfering Jun 23, 2025
@oconnor663
Copy link
Contributor Author

oconnor663 commented Jun 23, 2025

@zanieb suggested that special-casing setuptools might make more sense than taking a lock under /tmp. I'm going to look into that. (In that case we could still choose to take #14225, but it would no longer be related to this RP.)

@oconnor663 oconnor663 force-pushed the jack/lock_wheel_builds branch from 0019a4a to 04670c9 Compare June 25, 2025 18:40
@oconnor663 oconnor663 changed the title Make uv build lock its source dir, to prevent concurrent builds from interfering Lock the source tree when running setuptools, to protect concurrent builds Jun 25, 2025
@oconnor663
Copy link
Contributor Author

Just put up a new iteration. I've kept the same locking strategy (a cache_digest-named file under temp_dir()), but I've made it specific to setuptools, and we take the lock before we invoke any setuptools commands, including get_requires_for.... I noticed that even that read-only-sounding command creates *.egg-info, and even though I haven't seen that lead to failures when multiple processes do it at once, it seems safer to protect it. @konstin do you have time to take a look?

@oconnor663 oconnor663 temporarily deployed to uv-test-registries June 25, 2025 18:45 — with GitHub Actions Inactive
debug!(
r#"Calling `{}.build_{}("{}", {})`"#,
pep517_backend.backend,
self.pep517_backend.backend,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are drive-by cleanup.

Copy link
Member

@konstin konstin left a comment

Choose a reason for hiding this comment

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

This makes sense to me

@charliermarsh
Copy link
Member

I'm not a huge fan of special-casing setuptools but I don't feel strongly enough to advocate for a change.

@charliermarsh
Copy link
Member

(Actually just ignore my comment, it's alright.)

@oconnor663 oconnor663 had a problem deploying to uv-test-registries June 26, 2025 16:27 — with GitHub Actions Failure
Standard lock guards have the same annotation, because creating them
without binding them to a local variable is almost always a mistake.
@oconnor663 oconnor663 force-pushed the jack/lock_wheel_builds branch from 04670c9 to 2a44332 Compare June 26, 2025 17:03
@oconnor663
Copy link
Contributor Author

(rebasing to pick up test fixes from main)

@oconnor663 oconnor663 temporarily deployed to uv-test-registries June 26, 2025 17:06 — with GitHub Actions Inactive
@oconnor663 oconnor663 merged commit d4d6ede into main Jun 26, 2025
210 of 211 checks passed
@oconnor663 oconnor663 deleted the jack/lock_wheel_builds branch June 26, 2025 19:28
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Jun 29, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.7.14` -> `0.7.16` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.7.16`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0716)

[Compare Source](astral-sh/uv@0.7.15...0.7.16)

##### Python

- Add Python 3.14.0b3

See the
[`python-build-standalone` release notes](https://github.com/astral-sh/python-build-standalone/releases/tag/20250626)
for more details.

##### Enhancements

- Include path or URL when failing to convert in lockfile ([#&#8203;14292](astral-sh/uv#14292))
- Warn when `~=` is used as a Python version specifier without a patch version ([#&#8203;14008](astral-sh/uv#14008))

##### Preview features

- Ensure preview default Python installs are upgradeable ([#&#8203;14261](astral-sh/uv#14261))

##### Performance

- Share workspace cache between lock and sync operations ([#&#8203;14321](astral-sh/uv#14321))

##### Bug fixes

- Allow local indexes to reference remote files ([#&#8203;14294](astral-sh/uv#14294))
- Avoid rendering desugared prefix matches in error messages ([#&#8203;14195](astral-sh/uv#14195))
- Avoid using path URL for workspace Git dependencies in `requirements.txt` ([#&#8203;14288](astral-sh/uv#14288))
- Normalize index URLs to remove trailing slash ([#&#8203;14245](astral-sh/uv#14245))
- Respect URL-encoded credentials in redirect location ([#&#8203;14315](astral-sh/uv#14315))
- Lock the source tree when running setuptools, to protect concurrent builds ([#&#8203;14174](astral-sh/uv#14174))

##### Documentation

- Note that GCP Artifact Registry download URLs must have `/simple` component ([#&#8203;14251](astral-sh/uv#14251))

### [`v0.7.15`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0715)

[Compare Source](astral-sh/uv@0.7.14...0.7.15)

##### Enhancements

- Consistently use `Ordering::Relaxed` for standalone atomic use cases ([#&#8203;14190](astral-sh/uv#14190))
- Warn on ambiguous relative paths for `--index` ([#&#8203;14152](astral-sh/uv#14152))
- Skip GitHub fast path when rate-limited ([#&#8203;13033](astral-sh/uv#13033))
- Preserve newlines in `schema.json` descriptions ([#&#8203;13693](astral-sh/uv#13693))

##### Bug fixes

- Add check for using minor version link when creating a venv on Windows ([#&#8203;14252](astral-sh/uv#14252))
- Strip query parameters when parsing source URL ([#&#8203;14224](astral-sh/uv#14224))

##### Documentation

- Add a link to PyPI FAQ to clarify what per-project token is ([#&#8203;14242](astral-sh/uv#14242))

##### Preview features

- Allow symlinks in the build backend ([#&#8203;14212](astral-sh/uv#14212))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

concurrent wheel builds fail oddly

4 participants