| Crates.io | graceful_restart |
| lib.rs | graceful_restart |
| version | 0.1.6 |
| created_at | 2025-12-12 22:50:35.55869+00 |
| updated_at | 2025-12-18 06:26:32.094258+00 |
| description | Zero-downtime process restart library with signal handling / 零停机进程重启库,支持信号处理 |
| homepage | https://github.com/js0-site/rust/tree/main/graceful_restart |
| repository | https://github.com/js0-site/rust.git |
| max_upload_size | |
| id | 1982264 |
| size | 76,323 |
Add to your Cargo.toml:
[dependencies]
graceful_restart = "0.1.1"
This library is designed for web servers that need zero-downtime restarts. Each incoming request should acquire a read lock and release it when the request is completed.
use graceful_restart::{CANCEL, LOCK};
use std::sync::Arc;
async fn handle_request(request: Request) -> Response {
// Acquire read lock when request starts
let _guard = LOCK.read();
// Process the request normally
let response = process_request(request).await;
// Lock is automatically released when guard drops
response
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize xboot to activate global async calls
xboot::init().await?;
let listener = TcpListener::bind("127.0.0.1:8080").await?;
println!("Web server started - send SIGHUP to restart gracefully");
// Main server loop with cancellation support
loop {
tokio::select! {
result = listener.accept() => {
match result {
Ok((stream, _)) => {
tokio::spawn(async move {
handle_connection(stream).await;
});
}
Err(e) => eprintln!("Accept error: {e}"),
}
}
_ = CANCEL.cancelled() => {
println!("Shutdown signal received, stopping new connections");
break;
}
}
}
Ok(())
}
use graceful_restart::{CANCEL, LOCK};
async fn run_server() -> Result<(), Error> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
loop {
tokio::select! {
result = listener.accept() => {
match result {
Ok((stream, addr)) => {
println!("New connection from {addr}");
tokio::spawn(handle_client(stream));
}
Err(e) => eprintln!("Accept error: {e}"),
}
}
_ = CANCEL.cancelled() => {
println!("Server shutdown initiated");
break;
}
}
}
Ok(())
}
async fn handle_client(stream: TcpStream) {
let _guard = LOCK.read();
// Process client connection normally
process_connection(stream).await;
// Guard automatically released
}
The library implements graceful restart through signal handling and process management:
graph TD
A[Application Start] --> B[Signal Listener Active]
B --> C{Receive Signal}
C -->|SIGHUP| D[Create New Session]
D --> E[Spawn New Process]
E --> F[Notify System]
F --> G[Acquire Write Lock]
G --> H[Exit Current Process]
C -->|Other Signals| G
listen_signalgraceful_restart/
├── src/
│ └── lib.rs # Main library implementation
├── tests/
│ └── main.rs # Test cases and examples
├── readme/
│ ├── en.md # English documentation
│ └── zh.md # Chinese documentation
└── Cargo.toml # Project configuration
graceful_restart()Core async function that handles graceful restart operations. Automatically spawned as a background task via xboot::add!() during library initialization.
Behavior:
listen_signal::wait_all()CANCEL.cancel() to notify all active requests to stop accepting new worknix::unistd::setsid() (Linux only)LOCK.write() to wait for all active requests to complete, then performs graceful shutdownsys_notify::mainid() to track process transitionsNote: This function runs automatically in the background. Users don't need to call it directly, but must call xboot::init().await? in their main function to activate it.
LOCK: RwLock<()>Global read-write lock for coordinating web request handling and graceful shutdown.
Usage:
CANCEL: CancellationTokenGlobal cancellation token for signaling graceful shutdown to all active requests.
Usage:
CANCEL.cancelled() in tokio::select! to detect shutdown signalsThe concept of graceful restart has deep roots in Unix system administration. The SIGHUP signal, originally designed to notify processes of terminal hangups in the era of physical terminals and modems, evolved into a standard mechanism for configuration reloading and process restart.
Modern web servers like Nginx and Apache popularized zero-downtime restart patterns, allowing system administrators to update configurations or binary files without dropping active connections. This library brings similar capabilities to Rust web applications, using read-write locks to ensure that active HTTP requests complete before the process terminates, while new requests are handled by the restarted process.
This project is an open-source component of js0.site ⋅ Refactoring the Internet Plan.
We are redefining the development paradigm of the Internet in a componentized way. Welcome to follow us:
在 Cargo.toml 中添加:
[dependencies]
graceful_restart = "0.1.1"
本库专为需要零停机重启的网站服务器设计。每个传入请求应获取读锁,请求完成时释放锁。
use graceful_restart::{CANCEL, LOCK};
use std::sync::Arc;
async fn handle_request(request: Request) -> Response {
// 请求开始时获取读锁
let _guard = LOCK.read();
// 正常处理请求
let response = process_request(request).await;
// 守卫销毁时自动释放锁
response
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 初始化 xboot,激活全局异步调用,启动 graceful_restart() 函数
xboot::init().await?;
let listener = TcpListener::bind("127.0.0.1:8080").await?;
println!("网站服务器已启动 - 发送 SIGHUP 信号进行优雅重启");
// 带取消支持的主服务器循环
loop {
tokio::select! {
result = listener.accept() => {
match result {
Ok((stream, _)) => {
tokio::spawn(async move {
handle_connection(stream).await;
});
}
Err(e) => eprintln!("接受连接错误: {e}"),
}
}
_ = CANCEL.cancelled() => {
println!("收到关闭信号,停止接受新连接");
break;
}
}
}
Ok(())
}
use graceful_restart::{CANCEL, LOCK};
async fn run_server() -> Result<(), Error> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
loop {
tokio::select! {
result = listener.accept() => {
match result {
Ok((stream, addr)) => {
println!("来自 {addr} 的新连接");
tokio::spawn(handle_client(stream));
}
Err(e) => eprintln!("接受连接错误: {e}"),
}
}
_ = CANCEL.cancelled() => {
println!("服务器关闭启动");
break;
}
}
}
Ok(())
}
async fn handle_client(stream: TcpStream) {
let _guard = LOCK.read();
// 正常处理客户端连接
process_connection(stream).await;
// 守卫自动释放
}
库通过信号处理和进程管理实现优雅重启:
graph TD
A[应用启动] --> B[信号监听激活]
B --> C{接收信号}
C -->|SIGHUP| D[创建新会话]
D --> E[生成新进程]
E --> F[通知系统]
F --> G[获取写锁]
G --> H[退出当前进程]
C -->|其他信号| G
listen_signal 持续监听系统信号graceful_restart/
├── src/
│ └── lib.rs # 主要库实现
├── tests/
│ └── main.rs # 测试用例和示例
├── readme/
│ ├── en.md # 英文文档
│ └── zh.md # 中文文档
└── Cargo.toml # 项目配置
graceful_restart()处理优雅重启操作的核心异步函数。通过 xboot::add!() 在库初始化期间自动作为后台任务生成。
行为:
listen_signal::wait_all() 持续监听系统信号CANCEL.cancel() 通知所有活跃请求停止接受新工作nix::unistd::setsid() 生成具有会话隔离的新进程(仅限 Linux)LOCK.write() 获取写锁等待所有活跃请求完成,然后执行优雅关闭sys_notify::mainid() 与系统通知集成,跟踪进程转换注意: 此函数在后台自动运行。用户无需直接调用,但必须在主函数中调用 xboot::init().await? 来激活它。
LOCK: RwLock<()>用于协调网站请求处理和优雅关闭的全局读写锁。
用法:
CANCEL: CancellationToken用于向所有活跃请求发送优雅关闭信号的全局取消令牌。
用法:
tokio::select! 中使用 CANCEL.cancelled() 检测关闭信号优雅重启概念在 Unix 系统管理中有着深厚的历史根源。SIGHUP 信号最初设计用于在物理终端和调制解调器时代通知进程终端挂断,后来演变为配置重载和进程重启的标准机制。
现代 Web 服务器如 Nginx 和 Apache 普及了零停机重启模式,允许系统管理员在不丢失活动连接的情况下更新配置或二进制文件。本库将类似功能引入 Rust 网站应用程序,使用读写锁确保活跃的 HTTP 请求在进程终止前完成,而新请求由重启后的进程处理。
本项目为 js0.site ⋅ 重构互联网计划 的开源组件。
我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注: