这是indexloc提供的服务,不要输入任何密码
Skip to content

feat(process): distinguish between signals used to kill children #10049

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

Merged
merged 10 commits into from
Mar 12, 2025

Conversation

chris-olszewski
Copy link
Member

Description

This is a redo of #10027 with some additional refactoring to reduce the complexity of this code. These changes should lessens the possibilities of deadlock or race conditions.

I highly recommend viewing each commit individually.

From original PR:

This is primarily a code move of the ProcessManager out of the turborepo-lib crate. We also now differ between a child shutting down in response to a SIGINT vs us killing the child.

Future PR will be changing how we treat each of these exit outcomes.

The additional commits in this PR:

  • Fixed a race condition between between the 2 waits performed by the ChildStateManager where one was called by the task the sent a shutdown to the child and the other was the default wait. If the latter won, then it would appear another entity killed the child even when it was really us.
  • Changed the return value of ShutdownStyle::process to avoid returning an impossible state
  • Remove unused ChildState::Exited field which was never read
  • Removed shared state between the child handle and the child state manager
  • Simplified child methods

The removal of the shared state is possible since we already have the exit channel shared between the handles and the manager. Using both a channel and state was error prone as it lead to the following possibilities:

  • What does it mean if the manager is still listening for commands, but the state shows the child as exited
  • What does it mean if the manager channel is closed, but the state shows the child is still running
    Instead we only use the command channel being open/closed as an indication of if the child is running. Once the manager sees the child exit, it will send the exit status via the channel and exit resulting in the channel being closed.

Testing Instructions

Existing test suite, ran with hyperfine 'cargo test' -r 500 to attempt to flush out any races.

Copy link

vercel bot commented Feb 26, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
examples-basic-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-designsystem-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-gatsby-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-kitchensink-blog ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-native-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-nonmonorepo ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-svelte-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-tailwind-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
examples-vite-web ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm
turbo-site ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 5:27pm

child.stop().await.ok();
};

let (_, code) = join! {
Copy link
Member Author

Choose a reason for hiding this comment

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

With the lack of state, we no longer need to drive both futures to completion at the same time. Sending the stop command will complete:

  • Once the child manager reads the command from the channel
  • If the child manager exits and closes the command channel

After either of these we can wait for the exit code to be reported:

  • If the stop command was read, then the child manager will update the exit status based on the outcome of issuing the command
  • If the stop command was dropped, then the child manager has exited and will have dropped the sender for the exit status channel. If the sender for a watch channel is dropped then changed() will exit.

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.

2 participants