home
NOTE: Under Construction - I'm in the middle of upgrading my site and lots of stuff is kinda broken. Please forgive the mess.

Use Control-C To Stop A Rust Process That's Using watchexec

I'm using the watchexec we Rust crate to run my site generate process every time a file changes. It's the same create that powers cargo watch cw.

I ran into a problem with it where once I started it it CTRLC wouldn't stop it because it captured the signal. That makes sense, but meant the only way I could stop the process was to kill the terminal window.

This is what I came up with to catch the Interrupt signal that's sent by control-c in watchexec and tell it to stop itself via an `Outcome::Exitrust signal:

April 2023
Code
use core::fmt::Error;
use miette::Result;
use watchexec::action::Action;
use watchexec::action::Outcome;
use watchexec::config::InitConfig;
use watchexec::config::RuntimeConfig;
use watchexec::Watchexec;
use watchexec_signals::Signal;

#[tokio::main]
async fn main() -> Result<()> {
    println!("Starting process");
    let init = InitConfig::default();
    let mut runtime = RuntimeConfig::default();
    runtime.on_action(move |action: Action| async move {
         let mut stop: bool = false;
        action.events.iter().for_each(|event| {
            event.signals().for_each(|sig| match sig {
                Signal::Interrupt => {
                    println!("Caught Interrupt: Stopping");
                    stop = true;
                }
                _ => {}
            });
        });
        // TODO: put in if statement here that checks
        // for if the stop toggle has been switched
        action.outcome(Outcome::Exit);
        Ok::<(), Error>(())
    });
    let we = Watchexec::new(init, runtime)?;
    we.main().await.unwrap().unwrap();
    Ok(())
}

That's relatively concise, but I expect there's ways to tighten it up. In the mean time, it's doing what I need.

═══ § ═══

Footnotes And References