Skip to content

Commit 2eb1ca9

Browse files
committed
Refactor error handling and settings management: update implementation structure and add initial settings module
1 parent e797d59 commit 2eb1ca9

6 files changed

Lines changed: 128 additions & 126 deletions

File tree

src/models/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct ErrorResp {
2222
}
2323

2424

25-
// ------- Implementations -------
25+
// ------- Implementations ------- //
2626

2727

2828
impl fmt::Display for AppError {

src/models/initial.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use std::env::var as env_var;
2+
use std::time::Duration;
3+
4+
5+
pub struct PgSettings {
6+
pub url: String,
7+
pub conn_timeout: u64,
8+
pub max_pool_size: usize,
9+
pub wait_timeout: u64,
10+
pub new_connection_timeout: u64,
11+
pub recycle_timeout: u64,
12+
pub warm_pool: bool,
13+
pub warm_pool_size: usize,
14+
}
15+
16+
17+
pub struct MokaSettings {
18+
pub cache_size: u64,
19+
pub expiration_time: Duration,
20+
}
21+
22+
23+
pub struct AppSettings {
24+
pub pg_settings: PgSettings,
25+
pub cache_settings: MokaSettings,
26+
pub enable_logging: bool,
27+
}
28+
29+
30+
// ------- Implementations ------- //
31+
32+
33+
impl PgSettings {
34+
fn from_env() -> Self {
35+
let url = env_var("POSTGRES_DB_URL").expect("POSTGRES_DB_URL must be set");
36+
let conn_timeout = env_var("PG_CONN_TIMEOUT")
37+
.ok()
38+
.and_then(|s| s.parse().ok())
39+
.expect("PG_CONN_TIMEOUT must be a positive integer of type u64");
40+
let max_pool_size = env_var("PG_POOL_MAX_SIZE")
41+
.ok()
42+
.and_then(|s| s.parse().ok())
43+
.expect("PG_POOL_MAX_SIZE must be a positive integer of type usize");
44+
let wait_timeout = env_var("PG_POOL_WAIT_TIMEOUT")
45+
.ok()
46+
.and_then(|s| s.parse().ok())
47+
.expect("PG_POOL_WAIT_TIMEOUT must be a positive integer of type u64");
48+
let new_connection_timeout = env_var("PG_POOL_NEW_CONNECTION_TIMEOUT")
49+
.ok()
50+
.and_then(|s| s.parse().ok())
51+
.expect("PG_POOL_NEW_CONNECTION_TIMEOUT must be a positive integer of type u64");
52+
let recycle_timeout = env_var("PG_POOL_RECYCLE_TIMEOUT")
53+
.ok()
54+
.and_then(|s| s.parse().ok())
55+
.expect("PG_POOL_RECYCLE_TIMEOUT must be a positive integer of type u64");
56+
let warm_pool = env_var("PG_POOL_WARM_POOL").expect("PG_POOL_WARM_POOL must be set as true or false");
57+
let warm_pool = match warm_pool.to_lowercase().as_str() {
58+
"true" => true,
59+
"false" => false,
60+
_ => panic!("PG_POOL_WARM_POOL must be set as true or false"),
61+
};
62+
let warm_pool_size = env_var("PG_POOL_WARM_POOL_SIZE")
63+
.ok()
64+
.and_then(|s| s.parse().ok())
65+
.expect("PG_POOL_WARM_POOL_SIZE must be a positive integer of type usize");
66+
67+
// Warm pool size can not go above 128 (if warm pool is enabled)
68+
if warm_pool_size > max_pool_size {
69+
panic!("PG_POOL_WARM_POOL_SIZE must be at most PG_POOL_MAX_SIZE, it can not go more than {}", max_pool_size);
70+
}
71+
if warm_pool && warm_pool_size > 128 {
72+
panic!("PG_POOL_WARM_POOL_SIZE must be at most 128, and the optimal size is 64");
73+
}
74+
75+
PgSettings {
76+
url,
77+
conn_timeout,
78+
max_pool_size,
79+
wait_timeout,
80+
new_connection_timeout,
81+
recycle_timeout,
82+
warm_pool,
83+
warm_pool_size,
84+
}
85+
}
86+
}
87+
88+
89+
impl MokaSettings {
90+
fn from_env() -> Self {
91+
let cache_size = env_var("CACHE_SIZE")
92+
.ok()
93+
.and_then(|s| s.parse().ok())
94+
.expect("CACHE_SIZE must be a positive integer of type u64");
95+
let expiration_time = env_var("CACHE_EXPIRATION_TIME")
96+
.ok()
97+
.and_then(|s| s.parse().ok())
98+
.expect("CACHE_EXPIRATION_TIME must be a positive integer of type u64");
99+
100+
MokaSettings {
101+
cache_size,
102+
expiration_time: Duration::from_secs(expiration_time),
103+
}
104+
}
105+
}
106+
107+
108+
impl AppSettings {
109+
pub fn from_env() -> Self {
110+
let enable_logging = env_var("ENABLE_LOGGING").expect("ENABLE_LOGGING must be set as true or false");
111+
let enable_logging = match enable_logging.to_lowercase().as_str() {
112+
"true" => true,
113+
"false" => false,
114+
_ => panic!("ENABLE_LOGGING must be set as true or false"),
115+
};
116+
117+
AppSettings {
118+
pg_settings: PgSettings::from_env(),
119+
cache_settings: MokaSettings::from_env(),
120+
enable_logging,
121+
}
122+
}
123+
}

src/models/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod initial;
12
pub mod errors;
23
pub mod notes;
34
pub mod user;

src/models/notes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub struct Notes {
1212
}
1313

1414

15-
// ------- Implementations -------
15+
// ------- Implementations ------- //
1616

1717

1818
impl fmt::Display for Notes {

src/models/user.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub struct SessionUser {
1616
}
1717

1818

19-
// ------- Implementations -------
19+
// ------- Implementations ------- //
2020

2121

2222
impl fmt::Display for SessionUser {

src/state.rs

Lines changed: 1 addition & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,14 @@
1+
use crate::models::initial::{AppSettings, MokaSettings, PgSettings};
12
use deadpool_postgres::{Manager, RecyclingMethod, Pool as PgPool};
23
use crate::utils::{process_channel, AppCache};
34
use deadpool::{managed::Timeouts, Runtime};
45
use actix_web::web::Data as webData;
56
use tokio_postgres::{Config, NoTls};
6-
use std::env::var as env_var;
77
use std::sync::mpsc::Sender;
88
use std::time::Duration;
99
use log::{info, warn};
1010

1111

12-
struct PgSettings {
13-
url: String,
14-
conn_timeout: u64,
15-
max_pool_size: usize,
16-
wait_timeout: u64,
17-
new_connection_timeout: u64,
18-
recycle_timeout: u64,
19-
warm_pool: bool,
20-
warm_pool_size: usize,
21-
}
22-
23-
24-
struct MokaSettings {
25-
cache_size: u64,
26-
expiration_time: Duration,
27-
}
28-
29-
30-
struct AppSettings {
31-
pg_settings: PgSettings,
32-
cache_settings: MokaSettings,
33-
enable_logging: bool,
34-
}
35-
36-
37-
trait FromEnv {
38-
fn from_env() -> Self;
39-
}
40-
41-
42-
impl FromEnv for PgSettings {
43-
fn from_env() -> Self {
44-
let url = env_var("POSTGRES_DB_URL").expect("POSTGRES_DB_URL must be set");
45-
let conn_timeout = env_var("PG_CONN_TIMEOUT")
46-
.ok()
47-
.and_then(|s| s.parse().ok())
48-
.expect("PG_CONN_TIMEOUT must be a positive integer of type u64");
49-
let max_pool_size = env_var("PG_POOL_MAX_SIZE")
50-
.ok()
51-
.and_then(|s| s.parse().ok())
52-
.expect("PG_POOL_MAX_SIZE must be a positive integer of type usize");
53-
let wait_timeout = env_var("PG_POOL_WAIT_TIMEOUT")
54-
.ok()
55-
.and_then(|s| s.parse().ok())
56-
.expect("PG_POOL_WAIT_TIMEOUT must be a positive integer of type u64");
57-
let new_connection_timeout = env_var("PG_POOL_NEW_CONNECTION_TIMEOUT")
58-
.ok()
59-
.and_then(|s| s.parse().ok())
60-
.expect("PG_POOL_NEW_CONNECTION_TIMEOUT must be a positive integer of type u64");
61-
let recycle_timeout = env_var("PG_POOL_RECYCLE_TIMEOUT")
62-
.ok()
63-
.and_then(|s| s.parse().ok())
64-
.expect("PG_POOL_RECYCLE_TIMEOUT must be a positive integer of type u64");
65-
let warm_pool = env_var("PG_POOL_WARM_POOL").expect("PG_POOL_WARM_POOL must be set as true or false");
66-
let warm_pool = match warm_pool.to_lowercase().as_str() {
67-
"true" => true,
68-
"false" => false,
69-
_ => panic!("PG_POOL_WARM_POOL must be set as true or false"),
70-
};
71-
let warm_pool_size = env_var("PG_POOL_WARM_POOL_SIZE")
72-
.ok()
73-
.and_then(|s| s.parse().ok())
74-
.expect("PG_POOL_WARM_POOL_SIZE must be a positive integer of type usize");
75-
76-
// Warm pool size can not go above 128 (if warm pool is enabled)
77-
if warm_pool_size > max_pool_size {
78-
panic!("PG_POOL_WARM_POOL_SIZE must be at most PG_POOL_MAX_SIZE, it can not go more than {}", max_pool_size);
79-
}
80-
if warm_pool && warm_pool_size > 128 {
81-
panic!("PG_POOL_WARM_POOL_SIZE must be at most 128, and the optimal size is 64");
82-
}
83-
84-
PgSettings {
85-
url,
86-
conn_timeout,
87-
max_pool_size,
88-
wait_timeout,
89-
new_connection_timeout,
90-
recycle_timeout,
91-
warm_pool,
92-
warm_pool_size,
93-
}
94-
}
95-
}
96-
97-
98-
impl FromEnv for MokaSettings {
99-
fn from_env() -> Self {
100-
let cache_size = env_var("CACHE_SIZE")
101-
.ok()
102-
.and_then(|s| s.parse().ok())
103-
.expect("CACHE_SIZE must be a positive integer of type u64");
104-
let expiration_time = env_var("CACHE_EXPIRATION_TIME")
105-
.ok()
106-
.and_then(|s| s.parse().ok())
107-
.expect("CACHE_EXPIRATION_TIME must be a positive integer of type u64");
108-
109-
MokaSettings {
110-
cache_size,
111-
expiration_time: Duration::from_secs(expiration_time),
112-
}
113-
}
114-
}
115-
116-
117-
impl FromEnv for AppSettings {
118-
fn from_env() -> Self {
119-
let enable_logging = env_var("ENABLE_LOGGING").expect("ENABLE_LOGGING must be set as true or false");
120-
let enable_logging = match enable_logging.to_lowercase().as_str() {
121-
"true" => true,
122-
"false" => false,
123-
_ => panic!("ENABLE_LOGGING must be set as true or false"),
124-
};
125-
126-
AppSettings {
127-
pg_settings: PgSettings::from_env(),
128-
cache_settings: MokaSettings::from_env(),
129-
enable_logging,
130-
}
131-
}
132-
}
133-
13412

13513
async fn warm_pool(pool: &PgPool, pg: &PgSettings) {
13614
// Warm pool to avoid first-hit latency

0 commit comments

Comments
 (0)