Merge pull request #192 from neon-mmd/optimize-and-make-code-idiomatic
Browse files- Cargo.lock +27 -0
- Cargo.toml +5 -3
- src/bin/websurfx.rs +5 -0
- src/cache/cacher.rs +1 -0
- src/lib.rs +7 -1
- src/server/routes.rs +15 -3
Cargo.lock
CHANGED
@@ -300,6 +300,12 @@ version = "0.10.3"
|
|
300 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
301 |
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
[[package]]
|
304 |
name = "async-trait"
|
305 |
version = "0.1.73"
|
@@ -1601,6 +1607,16 @@ version = "0.2.147"
|
|
1601 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1602 |
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
1603 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1604 |
[[package]]
|
1605 |
name = "linux-raw-sys"
|
1606 |
version = "0.4.5"
|
@@ -1729,6 +1745,15 @@ dependencies = [
|
|
1729 |
"autocfg 1.1.0",
|
1730 |
]
|
1731 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1732 |
[[package]]
|
1733 |
name = "mime"
|
1734 |
version = "0.3.17"
|
@@ -3677,6 +3702,7 @@ dependencies = [
|
|
3677 |
"actix-cors",
|
3678 |
"actix-files",
|
3679 |
"actix-web",
|
|
|
3680 |
"async-trait",
|
3681 |
"criterion",
|
3682 |
"dhat",
|
@@ -3687,6 +3713,7 @@ dependencies = [
|
|
3687 |
"handlebars",
|
3688 |
"log",
|
3689 |
"md5",
|
|
|
3690 |
"mlua",
|
3691 |
"once_cell",
|
3692 |
"rand 0.8.5",
|
|
|
300 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
301 |
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
302 |
|
303 |
+
[[package]]
|
304 |
+
name = "async-once-cell"
|
305 |
+
version = "0.5.3"
|
306 |
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
307 |
+
checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb"
|
308 |
+
|
309 |
[[package]]
|
310 |
name = "async-trait"
|
311 |
version = "0.1.73"
|
|
|
1607 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1608 |
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
1609 |
|
1610 |
+
[[package]]
|
1611 |
+
name = "libmimalloc-sys"
|
1612 |
+
version = "0.1.34"
|
1613 |
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1614 |
+
checksum = "25d058a81af0d1c22d7a1c948576bee6d673f7af3c0f35564abd6c81122f513d"
|
1615 |
+
dependencies = [
|
1616 |
+
"cc",
|
1617 |
+
"libc",
|
1618 |
+
]
|
1619 |
+
|
1620 |
[[package]]
|
1621 |
name = "linux-raw-sys"
|
1622 |
version = "0.4.5"
|
|
|
1745 |
"autocfg 1.1.0",
|
1746 |
]
|
1747 |
|
1748 |
+
[[package]]
|
1749 |
+
name = "mimalloc"
|
1750 |
+
version = "0.1.38"
|
1751 |
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1752 |
+
checksum = "972e5f23f6716f62665760b0f4cbf592576a80c7b879ba9beaafc0e558894127"
|
1753 |
+
dependencies = [
|
1754 |
+
"libmimalloc-sys",
|
1755 |
+
]
|
1756 |
+
|
1757 |
[[package]]
|
1758 |
name = "mime"
|
1759 |
version = "0.3.17"
|
|
|
3702 |
"actix-cors",
|
3703 |
"actix-files",
|
3704 |
"actix-web",
|
3705 |
+
"async-once-cell",
|
3706 |
"async-trait",
|
3707 |
"criterion",
|
3708 |
"dhat",
|
|
|
3713 |
"handlebars",
|
3714 |
"log",
|
3715 |
"md5",
|
3716 |
+
"mimalloc",
|
3717 |
"mlua",
|
3718 |
"once_cell",
|
3719 |
"rand 0.8.5",
|
Cargo.toml
CHANGED
@@ -27,9 +27,11 @@ once_cell = {version="1.18.0"}
|
|
27 |
error-stack = {version="0.4.0"}
|
28 |
async-trait = {version="0.1.73"}
|
29 |
regex = {version="1.9.4", features=["perf"]}
|
|
|
30 |
futures = {version="0.3.28"}
|
31 |
dhat = {version="0.3.2", optional = true}
|
32 |
-
|
|
|
33 |
|
34 |
[dev-dependencies]
|
35 |
rusty-hook = "^0.11.2"
|
@@ -55,10 +57,10 @@ debug = false # This should only be commented when testing with dhat profiler
|
|
55 |
split-debuginfo = '...'
|
56 |
debug-assertions = false
|
57 |
overflow-checks = false
|
58 |
-
lto =
|
59 |
panic = 'abort'
|
60 |
incremental = false
|
61 |
-
codegen-units =
|
62 |
rpath = false
|
63 |
strip = "debuginfo"
|
64 |
|
|
|
27 |
error-stack = {version="0.4.0"}
|
28 |
async-trait = {version="0.1.73"}
|
29 |
regex = {version="1.9.4", features=["perf"]}
|
30 |
+
smallvec = {version="1.11.0", features=["union", "serde"]}
|
31 |
futures = {version="0.3.28"}
|
32 |
dhat = {version="0.3.2", optional = true}
|
33 |
+
mimalloc = { version = "0.1.38", default-features = false }
|
34 |
+
async-once-cell = {version="0.5.3"}
|
35 |
|
36 |
[dev-dependencies]
|
37 |
rusty-hook = "^0.11.2"
|
|
|
57 |
split-debuginfo = '...'
|
58 |
debug-assertions = false
|
59 |
overflow-checks = false
|
60 |
+
lto = true
|
61 |
panic = 'abort'
|
62 |
incremental = false
|
63 |
+
codegen-units = 1
|
64 |
rpath = false
|
65 |
strip = "debuginfo"
|
66 |
|
src/bin/websurfx.rs
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
//! This module contains the main function which handles the logging of the application to the
|
4 |
//! stdout and handles the command line arguments provided and launches the `websurfx` server.
|
5 |
|
|
|
6 |
use std::net::TcpListener;
|
7 |
use websurfx::{config::parser::Config, run};
|
8 |
|
@@ -11,6 +12,10 @@ use websurfx::{config::parser::Config, run};
|
|
11 |
#[global_allocator]
|
12 |
static ALLOC: dhat::Alloc = dhat::Alloc;
|
13 |
|
|
|
|
|
|
|
|
|
14 |
/// The function that launches the main server and registers all the routes of the website.
|
15 |
///
|
16 |
/// # Error
|
|
|
3 |
//! This module contains the main function which handles the logging of the application to the
|
4 |
//! stdout and handles the command line arguments provided and launches the `websurfx` server.
|
5 |
|
6 |
+
use mimalloc::MiMalloc;
|
7 |
use std::net::TcpListener;
|
8 |
use websurfx::{config::parser::Config, run};
|
9 |
|
|
|
12 |
#[global_allocator]
|
13 |
static ALLOC: dhat::Alloc = dhat::Alloc;
|
14 |
|
15 |
+
#[cfg(not(feature = "dhat-heap"))]
|
16 |
+
#[global_allocator]
|
17 |
+
static GLOBAL: MiMalloc = MiMalloc;
|
18 |
+
|
19 |
/// The function that launches the main server and registers all the routes of the website.
|
20 |
///
|
21 |
/// # Error
|
src/cache/cacher.rs
CHANGED
@@ -17,6 +17,7 @@ use super::error::PoolError;
|
|
17 |
/// * `pool_size` - It stores the size of the connection pool (in other words the number of
|
18 |
/// connections that should be stored in the pool).
|
19 |
/// * `current_connection` - It stores the index of which connection is being used at the moment.
|
|
|
20 |
pub struct RedisCache {
|
21 |
connection_pool: Vec<ConnectionManager>,
|
22 |
pool_size: u8,
|
|
|
17 |
/// * `pool_size` - It stores the size of the connection pool (in other words the number of
|
18 |
/// connections that should be stored in the pool).
|
19 |
/// * `current_connection` - It stores the index of which connection is being used at the moment.
|
20 |
+
#[derive(Clone)]
|
21 |
pub struct RedisCache {
|
22 |
connection_pool: Vec<ConnectionManager>,
|
23 |
pool_size: u8,
|
src/lib.rs
CHANGED
@@ -14,7 +14,12 @@ use crate::server::routes;
|
|
14 |
|
15 |
use actix_cors::Cors;
|
16 |
use actix_files as fs;
|
17 |
-
use actix_web::{
|
|
|
|
|
|
|
|
|
|
|
18 |
use config::parser::Config;
|
19 |
use handlebars::Handlebars;
|
20 |
use handler::paths::{file_path, FileType};
|
@@ -68,6 +73,7 @@ pub fn run(listener: TcpListener, config: Config) -> std::io::Result<Server> {
|
|
68 |
.app_data(web::Data::new(config.clone()))
|
69 |
.wrap(cors)
|
70 |
.wrap(Logger::default()) // added logging middleware for logging.
|
|
|
71 |
// Serve images and static files (css and js files).
|
72 |
.service(
|
73 |
fs::Files::new("/static", format!("{}/static", public_folder_path))
|
|
|
14 |
|
15 |
use actix_cors::Cors;
|
16 |
use actix_files as fs;
|
17 |
+
use actix_web::{
|
18 |
+
dev::Server,
|
19 |
+
http::header,
|
20 |
+
middleware::{Compress, Logger},
|
21 |
+
web, App, HttpServer,
|
22 |
+
};
|
23 |
use config::parser::Config;
|
24 |
use handlebars::Handlebars;
|
25 |
use handler::paths::{file_path, FileType};
|
|
|
73 |
.app_data(web::Data::new(config.clone()))
|
74 |
.wrap(cors)
|
75 |
.wrap(Logger::default()) // added logging middleware for logging.
|
76 |
+
.wrap(Compress::default()) // compress request headers to reduce memory usage.
|
77 |
// Serve images and static files (css and js files).
|
78 |
.service(
|
79 |
fs::Files::new("/static", format!("{}/static", public_folder_path))
|
src/server/routes.rs
CHANGED
@@ -16,6 +16,10 @@ use handlebars::Handlebars;
|
|
16 |
use serde::Deserialize;
|
17 |
use tokio::join;
|
18 |
|
|
|
|
|
|
|
|
|
19 |
/// A named struct which deserializes all the user provided search parameters and stores them.
|
20 |
///
|
21 |
/// # Fields
|
@@ -158,10 +162,17 @@ async fn results(
|
|
158 |
page: u32,
|
159 |
req: &HttpRequest,
|
160 |
) -> Result<SearchResults, Box<dyn std::error::Error>> {
|
161 |
-
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
// fetch the cached results json.
|
164 |
-
let cached_results_json =
|
|
|
165 |
// check if fetched cache results was indeed fetched or it was an error and if so
|
166 |
// handle the data accordingly.
|
167 |
match cached_results_json {
|
@@ -206,6 +217,7 @@ async fn results(
|
|
206 |
|
207 |
results.add_style(&config.style);
|
208 |
redis_cache
|
|
|
209 |
.cache_results(&serde_json::to_string(&results)?, &url)
|
210 |
.await?;
|
211 |
Ok(results)
|
|
|
16 |
use serde::Deserialize;
|
17 |
use tokio::join;
|
18 |
|
19 |
+
// ---- Constants ----
|
20 |
+
/// Initialize redis cache connection once and store it on the heap.
|
21 |
+
const REDIS_CACHE: async_once_cell::OnceCell<RedisCache> = async_once_cell::OnceCell::new();
|
22 |
+
|
23 |
/// A named struct which deserializes all the user provided search parameters and stores them.
|
24 |
///
|
25 |
/// # Fields
|
|
|
162 |
page: u32,
|
163 |
req: &HttpRequest,
|
164 |
) -> Result<SearchResults, Box<dyn std::error::Error>> {
|
165 |
+
let redis_cache: RedisCache = REDIS_CACHE
|
166 |
+
.get_or_init(async {
|
167 |
+
// Initialize redis cache connection pool only one and store it in the heap.
|
168 |
+
RedisCache::new(&config.redis_url, 5).await.unwrap()
|
169 |
+
})
|
170 |
+
.await
|
171 |
+
.clone();
|
172 |
+
|
173 |
// fetch the cached results json.
|
174 |
+
let cached_results_json: Result<String, error_stack::Report<crate::cache::error::PoolError>> =
|
175 |
+
redis_cache.clone().cached_json(&url).await;
|
176 |
// check if fetched cache results was indeed fetched or it was an error and if so
|
177 |
// handle the data accordingly.
|
178 |
match cached_results_json {
|
|
|
217 |
|
218 |
results.add_style(&config.style);
|
219 |
redis_cache
|
220 |
+
.clone()
|
221 |
.cache_results(&serde_json::to_string(&results)?, &url)
|
222 |
.await?;
|
223 |
Ok(results)
|