My Solution to Deno Watch Mode Signal Handling
Source: Dev.to
Problem Overview
To fix the Deno watch mode issue, I researched both Deno and Node.js. I wanted to adopt Node.js’s approach but implement it in Rust for Deno.
Rust doesn’t have a built‑in process.kill() function like JavaScript to send signals, but we can simulate this using channels. When creating a channel, we get a sender (Tx) and a receiver (Rx) that work together, which helps avoid race conditions.
I created a pull request (PR) that uses a channel to allow the worker process to inform the watcher process when the INT signal is handled, instead of letting the watcher process handle and ignore it.
Solution
The core idea is to pass a channel sender to the worker process and have the worker notify the watcher when it has dealt with Ctrl+C. The watcher then listens on the channel instead of handling the signal directly.
Creating the Channel
// Create a channel before starting the worker process
let (ctrl_c_tx, mut ctrl_c_rx) = tokio::sync::mpsc::unbounded_channel::();
Passing the Sender to the Worker
let watcher_communicator = Arc::new(WatcherCommunicator::new(
WatcherCommunicatorOptions {
// Pass the sender to the worker
ctrl_c_tx: ctrl_c_tx.clone(),
},
));
Worker Notifies the Watcher
impl WatcherCommunicator {
// Public function to inform the watcher process
pub fn handle_ctrl_c(&self) -> Result> {
self.ctrl_c_tx.send(())
}
}
Replacing the INT Handler
// _ = deno_signals::ctrl_c() => {
_ = ctrl_c_rx.recv() => {
Implementation Details
Understanding how the signal API is implemented in Deno is essential. The Signal.rs file shows how the Deno.addSignalListener() or process.on(signalName, callback) API works. I am still searching for the optimal place to trigger the channel sender without breaking existing behavior.
Conclusion
Implementing this feature has been the most challenging task I’ve faced recently. Three months ago, I had never written a line of Rust, and now I’m contributing significant Rust code to Deno. I’m grateful to my professor, humphd, for encouraging everyone in class to get involved in the open‑source community. This semester has been a remarkable learning experience.