| Crates.io | systemd_reload |
| lib.rs | systemd_reload |
| version | 0.1.12 |
| created_at | 2025-12-12 07:51:00.051189+00 |
| updated_at | 2025-12-12 08:51:14.399737+00 |
| description | Zero-downtime process management for Rust applications / Rust应用零停机进程管理 |
| homepage | https://github.com/js0/rust/tree/main/systemd_reload |
| repository | https://github.com/js0/rust.git |
| max_upload_size | |
| id | 1981147 |
| size | 68,193 |
A high-performance Rust library that provides systemd-style process management with zero-downtime rolling updates, graceful shutdown, and configurable timeout handling.
Add to your Cargo.toml:
[dependencies]
systemd_reload = "0.1"
Basic usage:
use systemd_reload::{run, is_worker};
#[tokio::main]
async fn main() {
if is_worker() {
// Worker process: run your main application logic
run_application().await;
} else {
// Supervisor process: manage workers with 600 seconds timeout
run(600).await;
}
}
async fn run_application() {
// Your actual application code goes here
println!("Worker process started, PID: {}", std::process::id());
// Example: web server, background task, etc.
loop {
// Your business logic
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
RunThe main process manager that handles worker lifecycle.
impl Run {
pub fn new(timeout: u64) -> Self
pub async fn run(mut self)
}
Parameters:
timeout: Maximum seconds to wait for graceful worker shutdown before force killingExitRepresents process exit information.
pub struct Exit {
pub pid: u32,
pub code: Option<i32>,
}
run(timeout: u64) -> impl Future<Output = ()>Convenience function to create and run the process manager in one call.
Parameters:
timeout: Maximum seconds to wait for graceful worker shutdownExample:
// Wait up to 600 seconds for graceful shutdown
run(600).await;
is_worker() -> boolDetects if the current process is running in worker mode by checking the SYSTEMD_RELOAD_WORKER environment variable.
The library implements a supervisor-worker pattern with async message passing:
graph TD
A[Supervisor Process] --> B[Signal Handler]
A --> C[Worker Manager]
A --> D[Message Queue]
B --> E[SIGHUP: Rolling Update]
B --> F[SIGTERM/SIGINT: Shutdown]
C --> G[Spawn Worker]
C --> H[Monitor Worker]
C --> I[Handle Exit]
G --> J[Worker Process 1]
G --> K[Worker Process 2]
H --> D
I --> D
D --> L[Process Events]
L --> M[Supervisor Exits]
L --> N[Clean Shutdown]
systemd_reload/
├── src/
│ ├── lib.rs # Public API and exports
│ └── run.rs # Core Run struct implementation
├── tests/
│ └── main.rs # Integration tests
├── readme/
│ ├── en.md # English documentation
│ └── zh.md # Chinese documentation
└── Cargo.toml # Project configuration
use systemd_reload::{run, is_worker};
use log::info;
#[tokio::main]
async fn main() {
if is_worker() {
// Worker process: run your web server
start_web_server().await;
} else {
// Supervisor process: manage workers with 600 seconds timeout
info!("Starting supervisor");
run(600).await;
}
}
async fn start_web_server() {
info!("Web server started, PID: {}", std::process::id());
// Example web server setup
// let app = axum::Router::new().route("/", axum::routing::get(handler));
// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
// .serve(app.into_make_service())
// .await
// .unwrap();
// Placeholder for demonstration
loop {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
use systemd_reload::is_worker;
use std::env;
fn main() {
// Initially not a worker
assert!(!is_worker());
// Set environment variable
unsafe {
env::set_var("SYSTEMD_RELOAD_WORKER", "true");
}
assert!(is_worker());
// Clean up
unsafe {
env::remove_var("SYSTEMD_RELOAD_WORKER");
}
assert!(!is_worker());
}
The concept of zero-downtime deployments has roots in telecommunications and mission-critical systems from the 1960s. The term "hot swapping" originated from the ability to replace hardware components without shutting down the system.
In software, this pattern gained prominence with:
systemd, released in 2010, brought this pattern to Linux system services with socket activation and service reloading. This library brings similar capabilities to Rust applications, leveraging modern async programming patterns for high-performance process management.
The supervisor-worker pattern used here is inspired by Erlang's "let it crash" philosophy, where supervisors monitor and restart failed workers, ensuring system resilience through isolation and recovery rather than prevention.
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:
高性能Rust库,提供systemd风格的进程管理,支持零停机滚动更新、优雅关闭和可配置的超时处理。
添加到 Cargo.toml:
[dependencies]
systemd_reload = "0.1"
基本用法:
use systemd_reload::{run, is_worker};
#[tokio::main]
async fn main() {
if is_worker() {
// Worker进程:运行主要应用逻辑
run_application().await;
} else {
// 监督者进程:管理worker,设置600秒超时
run(600).await;
}
}
async fn run_application() {
// 实际的应用代码放在这里
println!("Worker进程启动,PID: {}", std::process::id());
// 示例:Web服务器、后台任务等
loop {
// 业务逻辑
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
Run主进程管理器,处理worker生命周期。
impl Run {
pub fn new(timeout: u64) -> Self
pub async fn run(mut self)
}
参数:
timeout: 强制终止worker前等待优雅关闭的最大秒数Exit表示进程退出信息。
pub struct Exit {
pub pid: u32,
pub code: Option<i32>,
}
run(timeout: u64) -> impl Future<Output = ()>便捷函数,一次调用创建并运行进程管理器。
参数:
timeout: 优雅关闭等待的最大秒数示例:
// 等待最多600秒进行优雅关闭
run(600).await;
is_worker() -> bool通过检查 SYSTEMD_RELOAD_WORKER 环境变量来检测当前进程是否运行在worker模式。
库实现了监督者-工作者模式,使用异步消息传递:
graph TD
A[监督者进程] --> B[信号处理器]
A --> C[Worker管理器]
A --> D[消息队列]
B --> E[SIGHUP: 滚动更新]
B --> F[SIGTERM/SIGINT: 关闭]
C --> G[生成Worker]
C --> H[监控Worker]
C --> I[处理退出]
G --> J[Worker进程1]
G --> K[Worker进程2]
H --> D
I --> D
D --> L[进程事件]
L --> M[监督者退出]
L --> N[优雅关闭]
systemd_reload/
├── src/
│ ├── lib.rs # 公共API和导出
│ └── run.rs # 核心Run结构体实现
├── tests/
│ └── main.rs # 集成测试
├── readme/
│ ├── en.md # 英文文档
│ └── zh.md # 中文文档
└── Cargo.toml # 项目配置
use systemd_reload::{run, is_worker};
use log::info;
#[tokio::main]
async fn main() {
if is_worker() {
// Worker进程:运行Web服务器
start_web_server().await;
} else {
// 监督者进程:管理worker,设置600秒超时
info!("启动监督者");
run(600).await;
}
}
async fn start_web_server() {
info!("Web服务器启动,PID: {}", std::process::id());
// Web服务器设置示例
// let app = axum::Router::new().route("/", axum::routing::get(handler));
// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
// .serve(app.into_make_service())
// .await
// .unwrap();
// 演示用占位符
loop {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
use systemd_reload::is_worker;
use std::env;
fn main() {
// 初始状态不是worker
assert!(!is_worker());
// 设置环境变量
unsafe {
env::set_var("SYSTEMD_RELOAD_WORKER", "true");
}
assert!(is_worker());
// 清理
unsafe {
env::remove_var("SYSTEMD_RELOAD_WORKER");
}
assert!(!is_worker());
}
零停机部署的概念起源于1960年代的电信和关键任务系统。"热插拔"一词最初指在不关闭系统的情况下更换硬件组件的能力。
在软件领域,这种模式的发展历程:
systemd于2010年发布,通过socket激活和服务重载将这种模式带到Linux系统服务中。本库将类似功能引入Rust应用,利用现代异步编程模式实现高性能进程管理。
这里使用的监督者-工作者模式受到Erlang"让它崩溃"哲学的启发,监督者监控并重启失败的工作者,通过隔离和恢复而非预防来确保系统弹性。
本项目为 js0.site ⋅ 重构互联网计划 的开源组件。
我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注: