Commit
Message
Changed Files (3)
-
modified contrib/search-hub-web.service
diff --git a/contrib/search-hub-web.service b/contrib/search-hub-web.service index 03f08ff..ec536e9 100644 --- a/contrib/search-hub-web.service +++ b/contrib/search-hub-web.service @@ -5,6 +5,7 @@ After=network.target [Service] Type=simple ExecStart=%h/.cargo/bin/search_hub serve --db-path %h/.local/share/search_hub/bookmarks.db +ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=5 -
modified src/main.rs
diff --git a/src/main.rs b/src/main.rs index 6c680b0..42fe82c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize}; use std::collections::{HashMap, VecDeque}; use std::fs; use std::path::PathBuf; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex, RwLock}; use tracing::{error, info}; const USER_AGENT: &str = concat!("search_hub/", env!("CARGO_PKG_VERSION")); @@ -326,8 +326,28 @@ async fn main() { match args.command { Command::Serve { port, db_path } => { let db_path = resolve_db_path(db_path, config.db_path.as_deref()); + let engines = Arc::new(RwLock::new(engines)); info!("Starting server on {}:{}", bind_address, port); let srv_cfg = web::ServerConfig { port, bind_address, page_size, workers }; + + let reload_engines = engines.clone(); + let config_path = config_path.clone(); + tokio::spawn(async move { + use tokio::signal::unix::{signal, SignalKind}; + let mut sig = signal(SignalKind::hangup()).expect("failed to register SIGHUP"); + loop { + sig.recv().await; + info!("SIGHUP received, reloading engines from config"); + let new_config = match &config_path { + Some(p) => Config::load_from(p), + None => Config::load(), + }; + let mut guard = reload_engines.write().unwrap(); + *guard = new_config.engines; + info!("Reloaded {} engines from config", guard.len()); + } + }); + if let Err(e) = web::run_server(&db_path.to_string_lossy(), srv_cfg, engines).await { error!("Server error: {}", e); } -
modified src/web.rs
diff --git a/src/web.rs b/src/web.rs index d968fb2..29d8676 100644 --- a/src/web.rs +++ b/src/web.rs @@ -3,7 +3,7 @@ use crate::search_engines::{EngineError, ResultEntry, SearchEngine}; use crate::storage; use actix_web::{get, web, App, HttpRequest, HttpResponse, HttpServer, Responder}; use rusqlite::Connection; -use std::sync::Mutex; +use std::sync::{Arc, Mutex, RwLock}; use std::time::Instant; use tera::Tera; use tracing::{error, info}; @@ -72,7 +72,7 @@ async fn search( query: web::Query<SearchQuery>, templates: web::Data<Tera>, db_pool: web::Data<DbPool>, - engines: web::Data<Vec<EngineConfig>>, + engines: web::Data<Arc<RwLock<Vec<EngineConfig>>>>, cfg: web::Data<ServerConfig>, ) -> impl Responder { let start = Instant::now(); @@ -109,13 +109,13 @@ async fn search( .build() .ok(); if let Some(client) = client { + let snapshot = engines.read().unwrap().clone(); let mut handles = Vec::new(); - let engines = engines.clone(); - for i in 0..engines.len() { - let engine_name = engines[i].name().to_string(); + for i in 0..snapshot.len() { + let engine_name = snapshot[i].name().to_string(); let q_owned = q.to_string(); let client = client.clone(); - let engines = engines.clone(); + let engines = snapshot.clone(); handles.push(tokio::spawn(async move { let t0 = Instant::now(); let timeout_dur = engines[i].timeout(); @@ -208,7 +208,7 @@ pub struct SearchQuery { pub async fn run_server( db_path: &str, cfg: ServerConfig, - engines: Vec<EngineConfig>, + engines: Arc<RwLock<Vec<EngineConfig>>>, ) -> std::io::Result<()> { let db_pool = web::Data::new(DbPool::new(db_path)); let engines = web::Data::new(engines);