DioxusLabs / DioxusLabs/dioxus
dx serve does not gracefully shutdown server on windows
- Dominant language
- Rust
- Stars
- 39.1k
- Forks
- 1.9k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 4
Description
**Problem**
Setting a ```Ctrl-C``` handler is ignored when run from dx serve despite working when running directly.
[```fn soft_kill(&mut self)```](https://github.com/DioxusLabs/dioxus/blob/2ee8ecd4775be52fc28b65b1ebe3db149b10b20d/packages/cli/src/build/builder.rs#L623) on windows is just calling taskkill which provides no meaningful way to detect a graceful shutdown. This is a problem for apps that want to flush data to disk on shutdown. ```fn soft_kill(&mut self)```'s docs state that it attempts to "Gracefully kill the process and all of its children" but that does not seem to be the case.
Why taskill command even without /F does not trigger graceful shutdown
> According to docs taskkill without /F sends a ```WM_CLOSE``` message to the target program's window, however console applications don't have a window to target so no graceful shutdown is trigged. taskkill does not send ```CTRL_C_EVENT``` or any other signal that can be caught by a console application.
> There is actually a hint that this is going on in dx serve as well, as if you look at the console output when hitting ```Ctrl-C``` you will see the following logs being output from taskkill:
> ```ERROR: The process with PID #### could not be terminated. This process can only be terminated forcefully (with /F option)```
> This happens because it realizes it is unable to send the ```WM_CLOSE``` message so gives up with that error message.
**Steps To Reproduce**
Steps to reproduce the behavior:
- Setup ```Ctrl-C``` Handler that calls some sort of graceful shutdown behavior.
- Run app using ```dx serve --platform web```
- Hit ```Ctrl-C``` in the console window
- Observe that your ```Ctrl-C``` Handler is not triggered
**Expected behavior**
Hitting ```Ctrl-C``` while running ```dx serve``` would forward the ```Ctrl-C``` event to the child process.
**Screenshots**
N/A
**Environment:**
- Dx version: 0.7.2-35351eb
- Rust version: rustc 1.94.0-nightly
- OS info: Windows 11
- App platform: web
**Possible Solution**
Just include the [```send_ctrlc```](https://crates.io/crates/send_ctrlc) crate in the dx cli crate, and then use the provided [```fn terminate(&mut self)```](https://docs.rs/send_ctrlc/0.6.0/send_ctrlc/trait.Interruptible.html#method.terminate) now callable on a ```tokio::process::Child``` which is what dx serve holds currently. This send's a ```CTRL_BREAK_EVENT``` on windows and ```SIGTERM``` on unix. ```CTRL_BREAK_EVENT``` is in fact handled as a ```Crtl-C``` in the popular handler crates.
If this solution is acceptable I can open a PR as well if needed.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.