-
-
Notifications
You must be signed in to change notification settings - Fork 638
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
Thread-local stdio handling to support concurrent pantsd clients #11536
Thread-local stdio handling to support concurrent pantsd clients #11536
Conversation
4219cdc
to
cc6eb14
Compare
53cf8e9
to
cd21f44
Compare
### Problem #11536 moves from using POSIX-level replacement of the `stdio` file descriptors `{0, 1, 2}`, to replacing `sys.std*` with a thread-local implementation. Unfortunately, Python `subprocess`/`Popen` APIs hardcode `{0, 1, 2}` rather than actually inspecting `sys.std*.fileno()`, and so usages of those APIs that use `std*=None` (i.e. "inherit" mode), will inherit intentionally dead/closed file handles under `pantsd`. PEX uses inherit mode when spawning `pip` (in order to pass through `stderr` to the parent process), and this runs afoul of the above behavior. Pants has used PEX as a library for a very long time, but 95% of usecases have now migrated to using PEX as a binary, with wrappers exposed via the `@rule` API. The `PluginResolver` that Pants uses to resolve its own code is the last usage of PEX as a library. ### Solution In a series of commits, introduce a "bootstrap" `Scheduler` that is able to resolve plugins after an `OptionsBootstrapper` has been created, but before creating the `BuildConfiguration` (which contains plugin information). ### Result Although Pants has some stray references to PEX APIs, it no longer uses PEX as a library to resolve dependencies. #11536 and #7654 are unblocked. In future, if the options required to construct a minimal scheduler can be further pruned, the bootstrap `Scheduler` might also be able to be used to create the `OptionsBootstrapper`, which would allow for addressing #10360.
cd21f44
to
f07797f
Compare
…ate, and implement stdio replacement in Rust. [ci skip-build-wheels]
f07797f
to
d129bed
Compare
Hey folks: this is ready for review. Sorry for the huge commit. |
Any tips for it, like read this file first? Or things you want us to look out for? |
@@ -147,3 +151,5 @@ env_logger = "0.5.4" | |||
prost = { git = "https://github.com/danburkert/prost", rev = "a1cccbcee343e2c444e1cd2738c7fba2599fc391" } | |||
prost-build = { git = "https://github.com/danburkert/prost", rev = "a1cccbcee343e2c444e1cd2738c7fba2599fc391" } | |||
prost-types = { git = "https://github.com/danburkert/prost", rev = "a1cccbcee343e2c444e1cd2738c7fba2599fc391" } | |||
# TODO: Stabilize before landing. | |||
console = { git = "https://github.com/stuhood/console", branch = "stuhood/term-target-for-arbitrary-handles" } |
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.
So right now we're relying on some changes you made in your own copy of this repo?
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.
Yea, I'll fork them to pantsbuild/pants
before landing.
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.
LGTM.
It would be good to address the ~2 TODOs or file.
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.
Epic!
src/python/pants/backend/python/goals/pytest_runner_integration_test.py
Outdated
Show resolved
Hide resolved
cc7c446
to
a5af6f4
Compare
|
||
/// | ||
/// If stdout is backed by a real file, returns it as a RawFd. All usage of `RawFd` is unsafe, | ||
/// but this method is additionally unsafe because the real file might have been closed by the |
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.
This comment is kind of confusing, since this method is not marked as a Rust unsafe
function. IIRC the libc
functions that manipulate RawFd
are generally unsafe, but that's not the same thing as this function that generates RawFd
being unsafe.
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.
The unsafety here is technically just the same unsafety that is possible for any RawFd
... this function will not directly panic: instead, the RawFd
that you get might already be closed. So the comment is probably misleading, yea.
[ci skip-build-wheels]
a5af6f4
to
4078b32
Compare
This was green aside from some flakes in Github Actions for macOS: opened #11617 for those. |
### Problem A few references to the deprecated `.pants.d/pantsd/pantsd.log` location survived after #11536. ### Solution Fixup the references to point to the new location at `.pants.d/pants.log`. [ci skip-rust] [ci skip-build-wheels]
### Problem Since migrating to thread-local `stdio` in #11536, explicit stdio rendering methods on `Session`/`Scheduler` have been dead code. But additionally, our UI fallback could hypothetically have been interacting with `std::io::std*` on fds `1,2`, which would cause a crash. ### Solution Remove some dead (and some dangerous!) code around stdio in `Scheduler`/`Session`, and isolate stderr handling to the UI crate. ### Result Probably fixes #11626. [ci skip-build-wheels]
…t. (#11731) ### Problem `pantsd` has closed the file handles associated with `sys.std*` (fds "0, 1, 2") since its early inception, and until #11536 it allowed exactly one client at a time in order to redirect those precise fd numbers to the client socket (via nailgun). It's likely that: 1. before #11536, between the closing of stdio and its replacement when a client connected, any attempt to interact with `sys.std*` or Rust's stdio file handles would crash. 2. after #11536, interactions with `sys.std*` or Rust's stdio file handles at _any_ time would crash. ### Solution Rather than closing `sys.std*` in `pantsd`, replace them with valid file handles as a backstop against code that has-not/cannot be updated to avoid touching them (such as Rust panic handlers). In the case of `stdout`/`stderr`, redirect them to append to the `pants.log`. ### Result Given what was reported on tokio-rs/tokio#3499, it's likely that this fixes #11364 by replacing the "panicked while processing panic" message with an actual panic message rendered in the `pants.log` (for which we can open a new ticket). [ci skip-rust] [ci skip-build-wheels]
Problem
In order to support concurrent
pantsd
clients, work spawned by each client (even into background threads) must interact with the relevantstdio
file handles. And when a client disconnects, spawned work should be able to continue to log to thepantsd.log
.Solution
Extract the thread/task-local aspects of our
logging
crate into astdio
crate that provides:Console
-awarelogging
destinationConsole
while a UI orInteractiveProcess
is runningsys.std*
replacementsResult
No user-visible impact, but one of the largest remaining blockers for #7654 is removed.