From d8bd2feb6ecd565ff617f17bfb90ce443e5d4295 Mon Sep 17 00:00:00 2001 From: neon_arch Date: Wed, 2 Aug 2023 20:05:39 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20new=20config=20option?= =?UTF-8?q?=20to=20manage=20threads=20and=20improve=20logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bin/websurfx.rs | 18 ++++++++++-------- src/config/parser.rs | 39 ++++++++++++++++++++++++++++++++++++--- src/lib.rs | 3 +++ websurfx/config.lua | 1 + 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/bin/websurfx.rs b/src/bin/websurfx.rs index d8d7f5c..57682d9 100644 --- a/src/bin/websurfx.rs +++ b/src/bin/websurfx.rs @@ -4,7 +4,6 @@ //! stdout and handles the command line arguments provided and launches the `websurfx` server. use std::net::TcpListener; - use websurfx::{config::parser::Config, run}; /// The function that launches the main server and registers all the routes of the website. @@ -18,13 +17,16 @@ async fn main() -> std::io::Result<()> { // Initialize the parsed config file. let config = Config::parse().unwrap(); - // Initializing logging middleware with level set to default or info. - if config.logging || config.debug { - use env_logger::Env; - env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - } - - log::info!("started server on port {}", config.port); + log::info!( + "started server on port {} and IP {}", + config.port, + config.binding_ip + ); + log::info!( + "Open http://{}:{}/ in your browser", + config.port, + config.binding_ip + ); let listener = TcpListener::bind((config.binding_ip.clone(), config.port))?; diff --git a/src/config/parser.rs b/src/config/parser.rs index a665246..81fa6b8 100644 --- a/src/config/parser.rs +++ b/src/config/parser.rs @@ -2,8 +2,9 @@ //! into rust readable form. use super::parser_models::Style; +use log::LevelFilter; use rlua::Lua; -use std::{collections::HashMap, format, fs, path::Path}; +use std::{collections::HashMap, format, fs, io::Write, path::Path, thread::available_parallelism}; // ------- Constants -------- static COMMON_DIRECTORY_NAME: &str = "websurfx"; @@ -23,6 +24,7 @@ static CONFIG_FILE_NAME: &str = "config.lua"; /// * `debug` - It stores the option to whether enable or disable debug mode. /// * `upstream_search_engines` - It stores all the engine names that were enabled by the user. /// * `request_timeout` - It stores the time (secs) which controls the server request timeout. +/// * `threads` - It stores the number of threads which controls the app will use to run. #[derive(Clone)] pub struct Config { pub port: u16, @@ -34,6 +36,7 @@ pub struct Config { pub debug: bool, pub upstream_search_engines: Vec, pub request_timeout: u8, + pub threads: u8, } /// Configuration options for the aggregator. @@ -64,6 +67,35 @@ impl Config { .load(&fs::read_to_string(Config::config_path()?)?) .exec()?; + let parsed_threads: u8 = globals.get::<_, u8>("threads")?; + + let debug: bool = globals.get::<_, bool>("debug")?; + let logging:bool= globals.get::<_, bool>("logging")?; + + // Initializing logging middleware with level set to default or info. + let mut log_level: LevelFilter = LevelFilter::Off; + if logging && debug == false { + log_level = LevelFilter::Info; + } else if debug { + log_level = LevelFilter::Trace; + }; + env_logger::Builder::new().filter(None, log_level).init(); + + let threads: u8 = if parsed_threads == 0 { + let total_num_of_threads:usize = available_parallelism()?.get() /2; + if debug || logging { + log::error!("Config Error: The value of `threads` option should be a non zero positive integer"); + log::info!("Falling back to using {} threads", total_num_of_threads) + } else { + std::io::stdout() + .lock() + .write_all(&format!("Config Error: The value of `threads` option should be a non zero positive integer\nFalling back to using {} threads\n", total_num_of_threads).into_bytes())?; + }; + total_num_of_threads as u8 + } else { + parsed_threads + }; + Ok(Config { port: globals.get::<_, u16>("port")?, binding_ip: globals.get::<_, String>("binding_ip")?, @@ -75,14 +107,15 @@ impl Config { aggregator: AggregatorConfig { random_delay: globals.get::<_, bool>("production_use")?, }, - logging: globals.get::<_, bool>("logging")?, - debug: globals.get::<_, bool>("debug")?, + logging, + debug, upstream_search_engines: globals .get::<_, HashMap>("upstream_search_engines")? .into_iter() .filter_map(|(key, value)| value.then_some(key)) .collect(), request_timeout: globals.get::<_, u8>("request_timeout")?, + threads, }) }) } diff --git a/src/lib.rs b/src/lib.rs index e226e14..ea81746 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,8 @@ pub fn run(listener: TcpListener, config: Config) -> std::io::Result { let handlebars_ref: web::Data = web::Data::new(handlebars); + let cloned_config_threads_opt: u8 = config.threads; + let server = HttpServer::new(move || { App::new() .app_data(handlebars_ref.clone()) @@ -70,6 +72,7 @@ pub fn run(listener: TcpListener, config: Config) -> std::io::Result { .service(routes::settings) // settings page .default_service(web::route().to(routes::not_found)) // error page }) + .workers(cloned_config_threads_opt as usize) // Start server on 127.0.0.1 with the user provided port number. for example 127.0.0.1:8080. .listen(listener)? .run(); diff --git a/websurfx/config.lua b/websurfx/config.lua index 73bffe7..4f2633c 100644 --- a/websurfx/config.lua +++ b/websurfx/config.lua @@ -1,6 +1,7 @@ -- ### General ### logging = true -- an option to enable or disable logs. debug = false -- an option to enable or disable debug mode. +threads = 10 -- the amount of threads that the app will use to run (the value should be greater than 0). -- ### Server ### port = "8080" -- port on which server should be launched