diff --git a/Cargo.lock b/Cargo.lock index 14b1932..71e1463 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -300,6 +300,12 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" +[[package]] +name = "async-once-cell" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb" + [[package]] name = "async-trait" version = "0.1.73" @@ -1601,6 +1607,16 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "libmimalloc-sys" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25d058a81af0d1c22d7a1c948576bee6d673f7af3c0f35564abd6c81122f513d" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.5" @@ -1729,6 +1745,15 @@ dependencies = [ "autocfg 1.1.0", ] +[[package]] +name = "mimalloc" +version = "0.1.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "972e5f23f6716f62665760b0f4cbf592576a80c7b879ba9beaafc0e558894127" +dependencies = [ + "libmimalloc-sys", +] + [[package]] name = "mime" version = "0.3.17" @@ -3677,6 +3702,7 @@ dependencies = [ "actix-cors", "actix-files", "actix-web", + "async-once-cell", "async-trait", "criterion", "dhat", @@ -3687,6 +3713,7 @@ dependencies = [ "handlebars", "log", "md5", + "mimalloc", "mlua", "once_cell", "rand 0.8.5", diff --git a/Cargo.toml b/Cargo.toml index 35cf219..43b2c3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,9 +27,11 @@ once_cell = {version="1.18.0"} error-stack = {version="0.4.0"} async-trait = {version="0.1.73"} regex = {version="1.9.4", features=["perf"]} +smallvec = {version="1.11.0", features=["union", "serde"]} futures = {version="0.3.28"} dhat = {version="0.3.2", optional = true} -smallvec = {version="1.11.0", features=["union", "serde"]} +mimalloc = { version = "0.1.38", default-features = false } +async-once-cell = {version="0.5.3"} [dev-dependencies] rusty-hook = "^0.11.2" @@ -55,10 +57,10 @@ debug = false # This should only be commented when testing with dhat profiler split-debuginfo = '...' debug-assertions = false overflow-checks = false -lto = 'thin' +lto = true panic = 'abort' incremental = false -codegen-units = 16 +codegen-units = 1 rpath = false strip = "debuginfo" diff --git a/src/bin/websurfx.rs b/src/bin/websurfx.rs index 9aa5b69..bc8e7ce 100644 --- a/src/bin/websurfx.rs +++ b/src/bin/websurfx.rs @@ -3,6 +3,7 @@ //! This module contains the main function which handles the logging of the application to the //! stdout and handles the command line arguments provided and launches the `websurfx` server. +use mimalloc::MiMalloc; use std::net::TcpListener; use websurfx::{config::parser::Config, run}; @@ -11,6 +12,10 @@ use websurfx::{config::parser::Config, run}; #[global_allocator] static ALLOC: dhat::Alloc = dhat::Alloc; +#[cfg(not(feature = "dhat-heap"))] +#[global_allocator] +static GLOBAL: MiMalloc = MiMalloc; + /// The function that launches the main server and registers all the routes of the website. /// /// # Error diff --git a/src/cache/cacher.rs b/src/cache/cacher.rs index 6932dea..b2508b5 100644 --- a/src/cache/cacher.rs +++ b/src/cache/cacher.rs @@ -17,6 +17,7 @@ use super::error::PoolError; /// * `pool_size` - It stores the size of the connection pool (in other words the number of /// connections that should be stored in the pool). /// * `current_connection` - It stores the index of which connection is being used at the moment. +#[derive(Clone)] pub struct RedisCache { connection_pool: Vec, pool_size: u8, diff --git a/src/lib.rs b/src/lib.rs index e76344b..97bff01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,12 @@ use crate::server::routes; use actix_cors::Cors; use actix_files as fs; -use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer}; +use actix_web::{ + dev::Server, + http::header, + middleware::{Compress, Logger}, + web, App, HttpServer, +}; use config::parser::Config; use handlebars::Handlebars; use handler::paths::{file_path, FileType}; @@ -68,6 +73,7 @@ pub fn run(listener: TcpListener, config: Config) -> std::io::Result { .app_data(web::Data::new(config.clone())) .wrap(cors) .wrap(Logger::default()) // added logging middleware for logging. + .wrap(Compress::default()) // compress request headers to reduce memory usage. // Serve images and static files (css and js files). .service( fs::Files::new("/static", format!("{}/static", public_folder_path)) diff --git a/src/server/routes.rs b/src/server/routes.rs index 5db9d09..e17a452 100644 --- a/src/server/routes.rs +++ b/src/server/routes.rs @@ -16,6 +16,10 @@ use handlebars::Handlebars; use serde::Deserialize; use tokio::join; +// ---- Constants ---- +/// Initialize redis cache connection once and store it on the heap. +const REDIS_CACHE: async_once_cell::OnceCell = async_once_cell::OnceCell::new(); + /// A named struct which deserializes all the user provided search parameters and stores them. /// /// # Fields @@ -158,10 +162,17 @@ async fn results( page: u32, req: &HttpRequest, ) -> Result> { - //Initialize redis cache connection struct - let mut redis_cache = RedisCache::new(&config.redis_url, 5).await?; + let redis_cache: RedisCache = REDIS_CACHE + .get_or_init(async { + // Initialize redis cache connection pool only one and store it in the heap. + RedisCache::new(&config.redis_url, 5).await.unwrap() + }) + .await + .clone(); + // fetch the cached results json. - let cached_results_json = redis_cache.cached_json(&url).await; + let cached_results_json: Result> = + redis_cache.clone().cached_json(&url).await; // check if fetched cache results was indeed fetched or it was an error and if so // handle the data accordingly. match cached_results_json { @@ -206,6 +217,7 @@ async fn results( results.add_style(&config.style); redis_cache + .clone() .cache_results(&serde_json::to_string(&results)?, &url) .await?; Ok(results)