update: add ArcSwap to update gauges lock-free

main
_ 2020-12-20 19:35:32 +00:00
parent b2b0bbc8fc
commit e5103d48bd
7 changed files with 43 additions and 4 deletions

8
Cargo.lock generated
View File

@ -46,6 +46,12 @@ version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
[[package]]
name = "arc-swap"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec5a4539a733493f412c4d0bb962748ea1f90f3dfdba9ff3ee18acbefc3b33f0"
[[package]] [[package]]
name = "arrayref" name = "arrayref"
version = "0.3.6" version = "0.3.6"
@ -1636,6 +1642,7 @@ name = "ptth_file_server"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arc-swap",
"handlebars", "handlebars",
"http", "http",
"hyper", "hyper",
@ -1682,6 +1689,7 @@ dependencies = [
"aho-corasick", "aho-corasick",
"always_equal", "always_equal",
"anyhow", "anyhow",
"arc-swap",
"base64 0.12.3", "base64 0.12.3",
"blake3", "blake3",
"chrono", "chrono",

View File

@ -9,6 +9,7 @@ license = "AGPL-3.0"
[dependencies] [dependencies]
anyhow = "1.0.34" anyhow = "1.0.34"
arc-swap = "1.1.0"
handlebars = "3.5.1" handlebars = "3.5.1"
http = "0.2.1" http = "0.2.1"
hyper = "0.13.8" hyper = "0.13.8"

View File

@ -6,6 +6,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use arc_swap::ArcSwap;
use hyper::{ use hyper::{
Body, Body,
Request, Request,
@ -98,7 +99,26 @@ async fn main () -> Result <(), anyhow::Error> {
config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ()) config_file.name.unwrap_or_else (|| "PTTH File Server".to_string ())
); );
let gauges = metrics::Gauges::new ().await?; let metrics_gauge = Arc::new (ArcSwap::from_pointee (None));
let gauge_writer = Arc::clone (&metrics_gauge);
tokio::spawn (async move {
let mut interval = tokio::time::interval (std::time::Duration::from_secs (2));
loop {
interval.tick ().await;
let new_gauges = match file_server::metrics::Gauges::new ().await {
Err (e) => {
error! ("Failed to update gauge metrics: {:?}", e);
continue;
},
Ok (x) => x,
};
let new_gauges = Arc::new (Some (new_gauges));
gauge_writer.store (new_gauges);
}
});
let state = Arc::new (State { let state = Arc::new (State {
config: file_server::Config { config: file_server::Config {
@ -106,6 +126,7 @@ async fn main () -> Result <(), anyhow::Error> {
}, },
handlebars, handlebars,
metrics_startup, metrics_startup,
metrics_gauge,
hidden_path: Some (path), hidden_path: Some (path),
}); });

View File

@ -10,6 +10,7 @@ license = "AGPL-3.0"
aho-corasick = "0.7.14" aho-corasick = "0.7.14"
anyhow = "1.0.34" anyhow = "1.0.34"
arc-swap = "1.1.0"
base64 = "0.12.3" base64 = "0.12.3"
blake3 = "0.3.7" blake3 = "0.3.7"
chrono = {version = "0.4.19", features = ["serde"]} chrono = {version = "0.4.19", features = ["serde"]}

View File

@ -35,6 +35,7 @@ pub struct Startup {
#[derive (Debug, serde::Serialize)] #[derive (Debug, serde::Serialize)]
pub struct Gauges { pub struct Gauges {
pub utc: DateTime <Utc>,
pub rss_mib: u64, pub rss_mib: u64,
} }
@ -48,6 +49,7 @@ impl Gauges {
let rss_mib = mem.rss ().get::<mebibyte> (); let rss_mib = mem.rss ().get::<mebibyte> ();
let x = Gauges { let x = Gauges {
utc: Utc::now (),
rss_mib, rss_mib,
}; };

View File

@ -12,8 +12,10 @@ use std::{
Path, Path,
PathBuf, PathBuf,
}, },
sync::Arc,
}; };
use arc_swap::ArcSwap;
use handlebars::Handlebars; use handlebars::Handlebars;
use serde::Serialize; use serde::Serialize;
use tokio::{ use tokio::{
@ -57,6 +59,7 @@ pub struct State {
pub config: Config, pub config: Config,
pub handlebars: handlebars::Handlebars <'static>, pub handlebars: handlebars::Handlebars <'static>,
pub metrics_startup: metrics::Startup, pub metrics_startup: metrics::Startup,
pub metrics_gauge: Arc <ArcSwap <Option <metrics::Gauges>>>,
pub hidden_path: Option <PathBuf>, pub hidden_path: Option <PathBuf>,
} }

View File

@ -53,7 +53,6 @@ pub fn password_is_bad (mut password: String) -> bool {
struct State { struct State {
file_server: file_server::State, file_server: file_server::State,
config: Config, config: Config,
gauges: RwLock <file_server::metrics::Gauges>,
client: Client, client: Client,
} }
@ -179,8 +178,11 @@ pub async fn run_server (
) )
-> Result <(), ServerError> -> Result <(), ServerError>
{ {
use std::convert::TryInto; use std::{
convert::TryInto,
};
use arc_swap::ArcSwap;
use http::status::StatusCode; use http::status::StatusCode;
let asset_root = asset_root.unwrap_or_else (PathBuf::new); let asset_root = asset_root.unwrap_or_else (PathBuf::new);
@ -202,6 +204,7 @@ pub async fn run_server (
let handlebars = file_server::load_templates (&asset_root)?; let handlebars = file_server::load_templates (&asset_root)?;
let metrics_startup = file_server::metrics::Startup::new (config_file.name); let metrics_startup = file_server::metrics::Startup::new (config_file.name);
let metrics_gauge = Arc::new (ArcSwap::from_pointee (None));
let state = Arc::new (State { let state = Arc::new (State {
file_server: file_server::State { file_server: file_server::State {
@ -210,12 +213,12 @@ pub async fn run_server (
}, },
handlebars, handlebars,
metrics_startup, metrics_startup,
metrics_gauge,
hidden_path, hidden_path,
}, },
config: Config { config: Config {
relay_url: config_file.relay_url, relay_url: config_file.relay_url,
}, },
gauges: RwLock::new (file_server::metrics::Gauges::new ().await?),
client, client,
}); });