mirror of
https://github.com/NetworkCats/rustyip.git
synced 2026-11-13 16:17:46 +00:00
feat: add graceful shutdown with SIGTERM handling and updater cancellation
This commit is contained in:
Generated
+20
@@ -329,6 +329,12 @@ version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.32"
|
||||
@@ -1104,6 +1110,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"static-files",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
@@ -1434,6 +1441,19 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.5.3"
|
||||
|
||||
@@ -15,6 +15,7 @@ reqwest = { version = "0.13", default-features = false, features = ["rustls"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
dotenvy = "0.15"
|
||||
tokio-util = "0.7"
|
||||
static-files = "0.3.1"
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -25,4 +25,6 @@ RUN chown -R rustyip:rustyip /app
|
||||
|
||||
USER rustyip
|
||||
|
||||
STOPSIGNAL SIGTERM
|
||||
|
||||
ENTRYPOINT ["rustyip"]
|
||||
|
||||
+31
-5
@@ -1,6 +1,7 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use tracing::error;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{error, info};
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use rustyip::{config, db, handlers, routes, updater};
|
||||
@@ -32,12 +33,14 @@ async fn main() {
|
||||
};
|
||||
|
||||
let shared_db = db::new_shared(reader);
|
||||
let cancel = CancellationToken::new();
|
||||
|
||||
updater::spawn_updater(
|
||||
let updater_handle = updater::spawn_updater(
|
||||
shared_db.clone(),
|
||||
db_path,
|
||||
config.db_update_url,
|
||||
config.db_update_interval_hours,
|
||||
cancel.clone(),
|
||||
);
|
||||
|
||||
let state = handlers::AppState {
|
||||
@@ -56,10 +59,33 @@ async fn main() {
|
||||
.with_graceful_shutdown(shutdown_signal())
|
||||
.await
|
||||
.expect("server error");
|
||||
|
||||
info!("server stopped, cleaning up background tasks");
|
||||
cancel.cancel();
|
||||
let _ = updater_handle.await;
|
||||
info!("shutdown complete");
|
||||
}
|
||||
|
||||
async fn shutdown_signal() {
|
||||
tokio::signal::ctrl_c()
|
||||
.await
|
||||
.expect("failed to listen for ctrl+c");
|
||||
let ctrl_c = async {
|
||||
tokio::signal::ctrl_c()
|
||||
.await
|
||||
.expect("failed to listen for ctrl+c");
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
let terminate = async {
|
||||
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
|
||||
.expect("failed to listen for SIGTERM")
|
||||
.recv()
|
||||
.await;
|
||||
};
|
||||
|
||||
#[cfg(not(unix))]
|
||||
let terminate = std::future::pending::<()>();
|
||||
|
||||
tokio::select! {
|
||||
() = ctrl_c => info!("received SIGINT, shutting down"),
|
||||
() = terminate => info!("received SIGTERM, shutting down"),
|
||||
}
|
||||
}
|
||||
|
||||
+13
-4
@@ -4,7 +4,9 @@ use std::time::Duration;
|
||||
|
||||
use tokio::fs;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::error;
|
||||
use tokio::task::JoinHandle;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::db::{DbReader, SharedDb, load_db};
|
||||
|
||||
@@ -55,16 +57,23 @@ pub fn spawn_updater(
|
||||
db_path: PathBuf,
|
||||
update_url: String,
|
||||
interval_hours: u64,
|
||||
) {
|
||||
cancel: CancellationToken,
|
||||
) -> JoinHandle<()> {
|
||||
tokio::spawn(async move {
|
||||
let interval = Duration::from_secs(interval_hours * 3600);
|
||||
loop {
|
||||
tokio::time::sleep(interval).await;
|
||||
tokio::select! {
|
||||
() = tokio::time::sleep(interval) => {}
|
||||
() = cancel.cancelled() => {
|
||||
info!("updater task cancelled, stopping");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Err(e) = update_db(&shared_db, &db_path, &update_url).await {
|
||||
error!("database update failed: {e}");
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
async fn update_db(
|
||||
|
||||
Reference in New Issue
Block a user