-
-
Notifications
You must be signed in to change notification settings - Fork 646
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
Merge/replace with_${python_obj}
context managers with use of allow_threads
#11722
Comments
Will this need to be done all-or-nothing, or can be incremental? I'd love to work on this one, I'm enjoying learning more about FFI and the GIL. |
It could be incremental: we could add function(s) next to the I've updated the description to call out one of the challenges and a potential design. |
OH. 😮 .. Alternatively, if we're able to implement FromPyObject for
...and get rid of EDIT: Filed dgrunwald/rust-cpython#260 about a potential way to remove |
### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See #11722 for how we might make this less likely in the future. [ci skip-build-wheels]
…sbuild#11723) ### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See pantsbuild#11722 for how we might make this less likely in the future. [ci skip-build-wheels]
…sbuild#11723) ### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See pantsbuild#11722 for how we might make this less likely in the future. [ci skip-build-wheels]
…errypick of #11723) ### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See #11722 for how we might make this less likely in the future. [ci skip-build-wheels]
…errypick of #11723) ### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See #11722 for how we might make this less likely in the future. [ci skip-build-wheels]
We no longer use the `with_executor` mechanism from #11722, as we can directly store an `Executor` on the `PyNailgunClient` cheaply. This allows us to use `Python.allow_threads()` for better parallelism. It's awkward that our Python code now has `PyExecutor` from Rust-Cpython and PyO3, and that those aren't compatible. But this is less offensive than the risk of one big change rather than an incremental migration. We can't yet migrate `PyNailgunSession` because `PyCancellationLatch` is used by `PySession`. -- This also improves our file organization. We use a new pattern of having a `register()` function in each `interface/` file to register that file's functions and classes on the single native extension module, which makes `interface.rs` less bloated.
…sbuild#11723) ### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See pantsbuild#11722 for how we might make this less likely in the future. [ci skip-build-wheels]# Delete this line to force CI to run the JVM tests. [ci skip-jvm-tests]
…errypick of #11723) (#13149) ### Problem By chance, a garbage collection thread started up and called `lease_files_in_graph` while I happened to be running Pants in the foreground. This caused a deadlock because `lease_files_in_graph` was not releasing the GIL before touching the `Graph` (via the `Scheduler`)... and foreground interactions with the `Graph` frequently need to acquire the GIL to check for equality. ### Solution Move the problematic call to `scheduler.all_digests()` under `allow_threads` and add a note. Additionally, move one other potentially-problematic method call under `allow_threads`. ### Result A rare (hopefully?) deadlock is prevented. See #11722 for how we might make this less likely in the future. [ci skip-build-wheels] [ci skip-jvm-tests]
@stuhood I'm confused on this one. The pyclasses already implement pants/src/rust/engine/src/externs/interface.rs Lines 830 to 841 in 4301cb4
|
They implement fn nailgun_server_await_shutdown(py: Python, nailgun_server: &nailgun::Server) -> PyUnitResult { |
I think I'm going to try to stick to the current implementation while porting to PyO3. Once that lands, it should be easier to make this change. |
The
with_$x
context managers add a bunch of noise, and are much less central than callingallow_threads
, which we should try to do in nearly all cases.Not calling
allow_threads
before calling various methods of theScheduler
/Session
(particularly anything to do with theGraph
) can cause deadlocks... not to mention meaning that we're holding the GIL over native code that might not need it. For example: #11723It's possible that these methods could be merged, replaced, or enhanced to also release the GIL when called. But a challenge is that each of the
with_$x
methods cannot callallow_threads
, because each of them need the GIL to dereference the pointer.One strawdesign that might work would be something like:
We'd then implement the hyptothetical
Unwrappable
trait for tuples of 1, 2, 3-ish python objects (PyScheduler
,PySession
, etc) allowing you to make a single call to unwrap all of them at once. The single call to the method would allow it to callallow_threads
, since you would not need to nest them.The text was updated successfully, but these errors were encountered: