Skip to content
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

[commands::run_server_process]: fix race condition #2077

Merged

Conversation

arvidj
Copy link
Contributor

@arvidj arvidj commented Feb 4, 2024

Fixes #2076

@codecov-commenter
Copy link

codecov-commenter commented Feb 4, 2024

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (69be532) 30.90% compared to head (ec2f336) 30.89%.
Report is 3 commits behind head on main.

❗ Current head ec2f336 differs from pull request most recent head b23a0a5. Consider uploading reports for the commit b23a0a5 to get more accurate results

Files Patch % Lines
src/commands.rs 0.00% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2077      +/-   ##
==========================================
- Coverage   30.90%   30.89%   -0.01%     
==========================================
  Files          52       52              
  Lines       19912    19914       +2     
  Branches     9617     9613       -4     
==========================================
  Hits         6153     6153              
+ Misses       7931     7929       -2     
- Partials     5828     5832       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

src/commands.rs Outdated
Comment on lines 95 to 97
let listener = runtime.block_on(async move {
tokio::net::UnixListener::bind(sp).expect("Failed to bind Unix socket")
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let listener = runtime.block_on(async move {
tokio::net::UnixListener::bind(sp).expect("Failed to bind Unix socket")
});
let listener = runtime.block_on(async move {
tokio::net::UnixListener::bind(sp)
})?;

Untested, but perhaps returning the error directly would be better (to preserve the original functionality).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Works well, I've pushed a fixup with this change.

src/commands.rs Outdated
@@ -89,6 +89,11 @@ fn run_server_process(startup_timeout: Option<Duration>) -> Result<ServerStartup
let runtime = Runtime::new()?;
let exe_path = env::current_exe()?;
let workdir = exe_path.parent().expect("executable path has no parent?!");

// Spawn a blocking task to bind the Unix socket
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe add a comment to explain that it has to be done here to avoid a race

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in latest version.

src/commands.rs Outdated
Comment on lines 96 to 97
let sp = socket_path.clone();
let listener = runtime.block_on(async move { tokio::net::UnixListener::bind(sp) })?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can be written let listener = tokio::net::UnixListener::bind(&socket_path.clone())?;

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 compiles, but when I run it I get:

$ ./target/debug/sccache --start-server
sccache: Starting the server...
thread 'main' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', src/commands.rs:98:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The way I understand it: the function run_server_process is not async. Therefore, you cannot call async functions in it without starting a Tokio runtime(?). tokio::net::UnixListener::bind is an async function. Therefore, you must call it inside a runtime.block_on call so that it runs in a runtime(?).

Copy link
Collaborator

Choose a reason for hiding this comment

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

The function is not, actually, async. https://docs.rs/tokio/latest/tokio/net/struct.UnixListener.html#method.bind But it does not want to run without a runtime.
So the following would work too, without an async block:

let listener = {
    let _guard = runtime.enter();
    tokio::net::UnixListener::bind(&socket_path.clone())?
};

Copy link
Contributor Author

@arvidj arvidj Feb 6, 2024

Choose a reason for hiding this comment

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

Indeed. I've pushed a fixup with your last suggestion.

@arvidj
Copy link
Contributor Author

arvidj commented Feb 7, 2024

Latest workflow failed due to clippy complaining about the clone of socket_path being redundant. I've removed the clone in the latest version.

@sylvestre sylvestre merged commit 1539987 into mozilla:main Feb 7, 2024
49 checks passed
@sylvestre
Copy link
Collaborator

many thanks
i will do a release now

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.

Race condition in [run_server_process] on master and sccache 0.7.4
5 participants