diff --git a/src/bin/ptth_relay.rs b/src/bin/ptth_relay.rs index a525580..cd78d21 100644 --- a/src/bin/ptth_relay.rs +++ b/src/bin/ptth_relay.rs @@ -1,5 +1,6 @@ use std::{ error::Error, + path::PathBuf, sync::Arc, }; @@ -21,7 +22,8 @@ async fn main () -> Result <(), Box > { .init () ; - let config_file = ptth::load_toml::load_public ("config/ptth_relay.toml"); + let config_path = PathBuf::from ("config/ptth_relay.toml"); + let config_file = ptth::load_toml::load_public (&config_path); info! ("ptth_relay Git version: {:?}", ptth::git_version::GIT_VERSION); @@ -30,7 +32,8 @@ async fn main () -> Result <(), Box > { forced_shutdown.wrap_server ( relay::run_relay ( Arc::new (RelayState::from (&config_file)), - shutdown_rx + shutdown_rx, + Some (config_path) ) ).await??; diff --git a/src/lib.rs b/src/lib.rs index d0551bb..bc89e25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -116,7 +116,7 @@ mod tests { let relay_state_2 = relay_state.clone (); let (stop_relay_tx, stop_relay_rx) = oneshot::channel (); let task_relay = spawn (async move { - relay::run_relay (relay_state_2, stop_relay_rx).await.unwrap (); + relay::run_relay (relay_state_2, stop_relay_rx, None).await.unwrap (); }); assert! (relay_state.list_servers ().await.is_empty ()); diff --git a/src/relay/mod.rs b/src/relay/mod.rs index 4af0314..6fbe3ca 100644 --- a/src/relay/mod.rs +++ b/src/relay/mod.rs @@ -663,9 +663,35 @@ pub fn load_templates (asset_root: &Path) Ok (handlebars) } +async fn reload_config ( + state: &Arc , + config_reload_path: &Path +) -> Option <()> { + use tokio::prelude::*; + + let mut f = tokio::fs::File::open (config_reload_path).await.ok ()?; + + let mut buffer = vec! [0u8; 4096]; + let bytes_read = f.read (&mut buffer).await.ok ()?; + buffer.truncate (bytes_read); + + let config_s = String::from_utf8 (buffer).ok ()?; + let new_config: ConfigFile = toml::from_str (&config_s).ok ()?; + + let new_config = Config::from (&new_config); + + let mut config = state.config.write ().await; + (*config) = new_config; + + debug! ("Loaded {} server tripcodes", config.server_tripcodes.len ()); + + Some (()) +} + pub async fn run_relay ( state: Arc , - shutdown_oneshot: oneshot::Receiver <()> + shutdown_oneshot: oneshot::Receiver <()>, + config_reload_path: Option ) -> Result <(), Box > { @@ -674,16 +700,16 @@ pub async fn run_relay ( 4000, )); - { - let mut tripcode_set = HashSet::new (); - let config = state.config.read ().await; - for (_, v) in config.server_tripcodes.iter () { - if ! tripcode_set.insert (v) { - panic! ("Two servers have the same tripcode. That is not allowed."); + if let Some (config_reload_path) = config_reload_path { + let state_2 = state.clone (); + tokio::spawn (async move { + let mut reload_interval = tokio::time::interval (Duration::from_secs (60)); + + loop { + reload_interval.tick ().await; + reload_config (&state_2, &config_reload_path).await; } - } - - info! ("Loaded {} server tripcodes", config.server_tripcodes.len ()); + }); } let make_svc = make_service_fn (|_conn| { @@ -701,8 +727,6 @@ pub async fn run_relay ( let server = Server::bind (&addr) .serve (make_svc); - - server.with_graceful_shutdown (async { shutdown_oneshot.await.ok (); diff --git a/todo.md b/todo.md index eb775f8..e100cd8 100644 --- a/todo.md +++ b/todo.md @@ -1,4 +1,3 @@ -- Reload relay config (or at least tripcodes) without downtime - "Preview as" feature for Markdown (It's not threaded through the relay yet) - Remote `tail -f` (_Complicated_) (Maybe use chunked encoding or something?) - Make a debug client to replicate the issue Firefox is having with turtling