signals.rs
Overview
This file provides the implementation for handling operating system signals within the application. It listens for specific signals such as SIGHUP, SIGINT, and SIGTERM and executes appropriate actions when these signals are received. The primary purpose is to ensure graceful shutdowns and runtime behavior adjustments, such as database rotation, by sending commands to worker threads. Signal handling is performed asynchronously in a dedicated thread to avoid blocking the main execution flow.
Function
init_signals
pub fn init_signals(tx: mpsc::Sender<WorkerCommand>) -> io::Result<JoinHandle<()>>
Purpose
Initializes the signal handling thread which listens for predefined Unix signals and sends corresponding commands to the worker via a message-passing channel.
Parameters
tx: mpsc::Sender<WorkerCommand>
A sending endpoint of a multi-producer, single-consumer (mpsc) channel used to communicateWorkerCommandmessages to the worker thread.
Returns
io::Result<JoinHandle<()>>
On success, returns aJoinHandlefor the spawned signal handling thread, wrapped in anio::Result. The handle can be used to manage or wait for the thread's completion. On failure, returns an I/O error.
Usage Example
use std::sync::mpsc;
use crate::block_subscriber::WorkerCommand;
let (tx, rx) = mpsc::channel();
let signal_thread = signals::init_signals(tx).expect("Failed to initialize signals");
Behavior and Implementation Details
Uses the
signal-hookcrate to create an iterator over the signals of interest:SIGHUP,SIGINT, andSIGTERM.Spawns a new thread named
"signal_handler"dedicated exclusively to signal processing.Inside the thread, it continuously listens for incoming signals:
SIGTERM:
Logs a warning.
Sends a
WorkerCommand::Shutdownmessage to the worker thread.Waits 2 seconds to allow cleanup operations.
Exits the process with status code 1.
SIGINT:
Logs a warning.
Immediately exits the process with status code 1.
SIGHUP:
Logs a warning.
Sends a
WorkerCommand::RotateDbmessage to the worker thread to trigger a database rotation.
Other signals:
Logs a warning about unhandled signals.
If sending commands through the channel fails (e.g., if the receiver has been dropped), error logs are emitted.
Interaction with Other Components
WorkerCommand(fromblock_subscribermodule):
This enum defines command variants such asShutdownandRotateDbwhich control worker thread behavior. Theinit_signalsfunction sends these commands to coordinate shutdown and database rotation procedures. Refer to theblock_subscriberfor details on worker command handling.Signal Handling using
signal-hookcrate:
The file leverages thesignal-hookcrate for safe and efficient Unix signal handling, which is crucial for graceful shutdown and runtime control signals. See thesignal handlingtopic for more on signal handling paradigms.Threading and concurrency:
Signal handling is isolated in its own thread to avoid blocking main application logic, using Rust's standard threading and synchronization primitives (mpsc,JoinHandle). This aligns with best practices described underconcurrency.
Important Implementation Details
The thread created is named
"signal_handler"to facilitate debugging and profiling.Upon receiving
SIGTERM, the delay of 2 seconds before exit allows the worker thread to perform any necessary cleanup such as database shutdown or transaction commits.The use of
exit(1)on signal receipt ensures the process terminates immediately after handling critical signals.The design ensures that signals are handled asynchronously, minimizing impact on main application performance.
Mermaid Diagram
flowchart TD
InitSignals["init_signals(tx)"]
SignalsIterator["signal_hook::iterator::Signals"]
SignalHandlerThread["Signal Handler Thread"]
InitSignals --> SignalsIterator
InitSignals --> SignalHandlerThread
SignalHandlerThread -->|Receives SIGTERM| SendShutdown["Send WorkerCommand::Shutdown"]
SignalHandlerThread -->|Receives SIGINT| ExitProcess1["exit(1)"]
SignalHandlerThread -->|Receives SIGHUP| SendRotateDb["Send WorkerCommand::RotateDb"]
SignalHandlerThread -->|Receives Other| LogWarning["Log unhandled signal"]
SendShutdown --> Sleep2s["Sleep 2 seconds"]
Sleep2s --> ExitProcess1
The diagram illustrates the flow in init_signals: initialization of signals iterator, spawning the signal handler thread, and the thread's reactions to various signals, including commands sent to the worker and process termination.
For more on thread management and message passing, see [threading and channels](/threading_channels). For details on worker commands and their processing, consult [block_subscriber](/block_subscriber).