diff --git a/README.md b/README.md index 3b13d49..cf7c149 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,7 @@ Assign a default value for each user-modifiable setting by passing environment v | `SUBSCRIPTIONS` | `+`-delimited list of subreddits (`sub1+sub2+sub3+...`) | _(none)_ | | `HIDE_AWARDS` | `["on", "off"]` | `off` | `DISABLE_VISIT_REDDIT_CONFIRMATION` | `["on", "off"]` | `off` | +| `DISABLE_STATS_COLLECTION | Any string to disable | _(none)_ | You can also configure Libreddit with a configuration file. An example `libreddit.toml` can be found below: diff --git a/app.json b/app.json index 0da7058..11c474c 100644 --- a/app.json +++ b/app.json @@ -58,6 +58,9 @@ }, "LIBREDDIT_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION": { "required": false + }, + "LIBREDDIT_DISABLE_STATS_COLLECTION": { + "required": false } } } diff --git a/src/client.rs b/src/client.rs index a89d28f..e2abd77 100644 --- a/src/client.rs +++ b/src/client.rs @@ -7,11 +7,11 @@ use libflate::gzip; use once_cell::sync::Lazy; use percent_encoding::{percent_encode, CONTROLS}; use serde_json::Value; -use std::{io, result::Result}; +use std::{io, result::Result, sync::atomic::Ordering::SeqCst}; -use crate::dbg_msg; use crate::instance_info::INSTANCE_INFO; use crate::server::RequestExt; +use crate::{config, dbg_msg}; const REDDIT_URL_BASE: &str = "https://www.reddit.com"; @@ -127,8 +127,9 @@ fn reddit_head(path: String, quarantine: bool) -> Boxed, S /// in its response. fn request(method: &'static Method, path: String, redirect: bool, quarantine: bool) -> Boxed, String>> { // Increment reddit request count. This will include head requests. - INSTANCE_INFO.reddit_requests.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - + if config::get_setting("LIBREDDIT_DISABLE_STATS_COLLECTION").is_none() { + INSTANCE_INFO.reddit_requests.fetch_add(1, SeqCst); + } // Build Reddit URL from path. let url = format!("{}{}", REDDIT_URL_BASE, path); diff --git a/src/config.rs b/src/config.rs index 4107582..698e3f2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -63,6 +63,9 @@ pub struct Config { #[serde(rename = "LIBREDDIT_ROBOTS_DISABLE_INDEXING")] pub(crate) robots_disable_indexing: Option, + + #[serde(rename = "LIBREDDIT_DISABLE_STATS_COLLECTION")] + pub(crate) disable_stats_collection: Option, } impl Config { @@ -94,6 +97,7 @@ impl Config { default_disable_visit_reddit_confirmation: parse("LIBREDDIT_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION"), banner: parse("LIBREDDIT_BANNER"), robots_disable_indexing: parse("LIBREDDIT_ROBOTS_DISABLE_INDEXING"), + disable_stats_collection: parse("LIBREDDIT_DISABLE_STATS_COLLECTION"), } } } @@ -116,6 +120,7 @@ fn get_setting_from_config(name: &str, config: &Config) -> Option { "LIBREDDIT_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION" => config.default_disable_visit_reddit_confirmation.clone(), "LIBREDDIT_BANNER" => config.banner.clone(), "LIBREDDIT_ROBOTS_DISABLE_INDEXING" => config.robots_disable_indexing.clone(), + "LIBREDDIT_DISABLE_STATS_COLLECTION" => config.disable_stats_collection.clone(), _ => None, } } @@ -162,3 +167,16 @@ fn test_alt_env_config_precedence() { fn test_default_subscriptions() { assert_eq!(get_setting("LIBREDDIT_DEFAULT_SUBSCRIPTIONS"), Some("news+bestof".into())); } + +#[test] +fn test_stats_collection_empty() { + assert_eq!(get_setting("LIBREDDIT_DISABLE_STATS_COLLECTION"), None); +} + +#[test] +#[sealed_test] +fn test_stats_collection_true() { + let config_to_write = r#"LIBREDDIT_DISABLE_STATS_COLLECTION = "1""#; + write("libreddit.toml", config_to_write).unwrap(); + assert!(get_setting("LIBREDDIT_DISABLE_STATS_COLLECTION").is_some()); +} \ No newline at end of file diff --git a/src/instance_info.rs b/src/instance_info.rs index 3a2cb05..9d34cd5 100644 --- a/src/instance_info.rs +++ b/src/instance_info.rs @@ -1,4 +1,4 @@ -use std::sync::atomic::AtomicU32; +use std::sync::atomic::{AtomicU32, Ordering::SeqCst}; use crate::{ config::{Config, CONFIG}, @@ -128,8 +128,9 @@ impl InstanceInfo { ["Deploy timestamp", &self.deploy_unix_ts.to_string()], ["Compile mode", &self.compile_mode], ["SFW only", &convert(&self.config.sfw_only)], - ["Reddit request count", &self.reddit_requests.load(std::sync::atomic::Ordering::SeqCst).to_string()], - ["Total request count", &self.total_requests.load(std::sync::atomic::Ordering::SeqCst).to_string()], + ["Disable stats collection", &convert(&self.config.disable_stats_collection)], + ["Reddit request count", &self.reddit_requests.load(SeqCst).to_string()], + ["Total request count", &self.total_requests.load(SeqCst).to_string()], ]) .with_header_row(["Settings"]), ); @@ -163,6 +164,7 @@ impl InstanceInfo { Deploy timestamp: {}\n Compile mode: {}\n SFW only: {:?}\n + Disable stats collection: {:?}\n Reddit request count: {}\n Total request count: {}\n Config:\n @@ -185,8 +187,9 @@ impl InstanceInfo { self.deploy_unix_ts, self.compile_mode, self.config.sfw_only, - self.reddit_requests.load(std::sync::atomic::Ordering::SeqCst), - self.total_requests.load(std::sync::atomic::Ordering::SeqCst), + self.config.disable_stats_collection, + self.reddit_requests.load(SeqCst), + self.total_requests.load(SeqCst), self.config.banner, self.config.default_hide_awards, self.config.default_theme, diff --git a/src/server.rs b/src/server.rs index f3fc844..9db7cba 100644 --- a/src/server.rs +++ b/src/server.rs @@ -20,10 +20,11 @@ use std::{ result::Result, str::{from_utf8, Split}, string::ToString, + sync::atomic::Ordering::SeqCst, }; use time::Duration; -use crate::{dbg_msg, instance_info::INSTANCE_INFO}; +use crate::{config, dbg_msg, instance_info::INSTANCE_INFO}; type BoxResponse = Pin, String>> + Send>>; @@ -234,8 +235,11 @@ impl Server { match router.recognize(&format!("/{}{}", req.method().as_str(), path)) { // If a route was configured for this path Ok(found) => { - // Add to total_requests count - INSTANCE_INFO.total_requests.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + if config::get_setting("LIBREDDIT_DISABLE_STATS_COLLECTION").is_none() { + // Add to total_requests count + INSTANCE_INFO.total_requests.fetch_add(1, SeqCst); + } + let mut parammed = req; parammed.set_params(found.params().clone());