Skip to content

Commit e725353

Browse files
committed
Remove duplicate initialization of dotenv
While doing memory profiling, I noticed that `dotenv` was being initialized each time the `env` helper function was called. With my `.env` file in development it was (temporarily) allocating 9.7MB on each call to the `env` helper. The `dotenv::var` helper uses `std::sync::Once` and avoids this duplicate work. I don't expect this to improve allocation patterns on production much, as without a `.env` file, only 1.9kB is (temporarily) allocated.
1 parent 8e5d17a commit e725353

File tree

8 files changed

+13
-34
lines changed

8 files changed

+13
-34
lines changed

src/controllers/user/session.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,10 @@ pub fn logout(req: &mut dyn Request) -> CargoResult<Response> {
133133
#[cfg(test)]
134134
mod tests {
135135
use super::*;
136-
use dotenv::dotenv;
137-
use std::env;
138136

139137
fn pg_connection() -> PgConnection {
140-
let _ = dotenv();
141138
let database_url =
142-
env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
139+
dotenv::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
143140
PgConnection::establish(&database_url).unwrap()
144141
}
145142

src/email.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use std::env;
21
use std::path::Path;
32

43
use crate::util::{bad_request, CargoResult};
5-
use dotenv::dotenv;
64

75
use lettre::file::FileTransport;
86
use lettre::smtp::authentication::{Credentials, Mechanism};
@@ -19,12 +17,10 @@ pub struct MailgunConfigVars {
1917
}
2018

2119
pub fn init_config_vars() -> Option<MailgunConfigVars> {
22-
dotenv().ok();
23-
2420
match (
25-
env::var("MAILGUN_SMTP_LOGIN"),
26-
env::var("MAILGUN_SMTP_PASSWORD"),
27-
env::var("MAILGUN_SMTP_SERVER"),
21+
dotenv::var("MAILGUN_SMTP_LOGIN"),
22+
dotenv::var("MAILGUN_SMTP_PASSWORD"),
23+
dotenv::var("MAILGUN_SMTP_SERVER"),
2824
) {
2925
(Ok(login), Ok(password), Ok(server)) => Some(MailgunConfigVars {
3026
smtp_login: login,

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ pub fn build_handler(app: Arc<App>) -> MiddlewareBuilder {
100100
/// Panics if the environment variable with the name passed in as an argument is not defined
101101
/// in the current environment.
102102
pub fn env(s: &str) -> String {
103-
dotenv::dotenv().ok();
104-
::std::env::var(s).unwrap_or_else(|_| panic!("must have `{}` defined", s))
103+
dotenv::var(s).unwrap_or_else(|_| panic!("must have `{}` defined", s))
105104
}
106105

107106
sql_function!(fn lower(x: ::diesel::sql_types::Text) -> ::diesel::sql_types::Text);

src/models/category.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,10 @@ impl<'a> NewCategory<'a> {
184184
mod tests {
185185
use super::*;
186186
use diesel::connection::SimpleConnection;
187-
use dotenv::dotenv;
188-
use std::env;
189187

190188
fn pg_connection() -> PgConnection {
191-
let _ = dotenv();
192189
let database_url =
193-
env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
190+
dotenv::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
194191
let conn = PgConnection::establish(&database_url).unwrap();
195192
// These tests deadlock if run concurrently
196193
conn.batch_execute("BEGIN; LOCK categories IN ACCESS EXCLUSIVE MODE")

src/models/keyword.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,10 @@ mod tests {
9999
use super::*;
100100
use diesel;
101101
use diesel::connection::SimpleConnection;
102-
use dotenv::dotenv;
103-
use std::env;
104102

105103
fn pg_connection() -> PgConnection {
106-
let _ = dotenv();
107104
let database_url =
108-
env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
105+
dotenv::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
109106
let conn = PgConnection::establish(&database_url).unwrap();
110107
// These tests deadlock if run concurrently
111108
conn.batch_execute("BEGIN;").unwrap();

src/tests/all.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use cargo_registry::{
2020
};
2121
use std::{
2222
borrow::Cow,
23-
env,
2423
sync::{
2524
atomic::{AtomicUsize, Ordering},
2625
Arc,
@@ -112,15 +111,13 @@ fn app() -> (
112111
Arc<App>,
113112
conduit_middleware::MiddlewareBuilder,
114113
) {
115-
dotenv::dotenv().ok();
116-
117114
let (proxy, bomb) = record::proxy();
118115
let uploader = Uploader::S3 {
119116
bucket: s3::Bucket::new(
120117
String::from("alexcrichton-test"),
121118
None,
122-
std::env::var("S3_ACCESS_KEY").unwrap_or_default(),
123-
std::env::var("S3_SECRET_KEY").unwrap_or_default(),
119+
dotenv::var("S3_ACCESS_KEY").unwrap_or_default(),
120+
dotenv::var("S3_SECRET_KEY").unwrap_or_default(),
124121
// When testing we route all API traffic over HTTP so we can
125122
// sniff/record it, but everywhere else we use https
126123
"http",
@@ -140,8 +137,8 @@ fn simple_app(uploader: Uploader) -> (Arc<App>, conduit_middleware::MiddlewareBu
140137
session_key: "test this has to be over 32 bytes long".to_string(),
141138
git_repo_checkout: git::checkout(),
142139
index_location: Url::from_file_path(&git::bare()).unwrap(),
143-
gh_client_id: env::var("GH_CLIENT_ID").unwrap_or_default(),
144-
gh_client_secret: env::var("GH_CLIENT_SECRET").unwrap_or_default(),
140+
gh_client_id: dotenv::var("GH_CLIENT_ID").unwrap_or_default(),
141+
gh_client_secret: dotenv::var("GH_CLIENT_SECRET").unwrap_or_default(),
145142
db_url: env("TEST_DATABASE_URL"),
146143
env: Env::Test,
147144
max_upload_size: 3000,
@@ -160,7 +157,7 @@ fn simple_app(uploader: Uploader) -> (Arc<App>, conduit_middleware::MiddlewareBu
160157

161158
// Return the environment variable only if it has been defined
162159
fn env(var: &str) -> String {
163-
match env::var(var) {
160+
match dotenv::var(var) {
164161
Ok(ref s) if s == "" => panic!("environment variable `{}` must not be empty", var),
165162
Ok(s) => s,
166163
_ => panic!(

src/tests/categories.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use cargo_registry::schema::categories;
2-
use std::env;
32

43
use diesel::*;
5-
use dotenv::dotenv;
64

75
const ALGORITHMS: &str = r#"
86
[algorithms]
@@ -40,9 +38,8 @@ description = "Another category ho hum"
4038
"#;
4139

4240
fn pg_connection() -> PgConnection {
43-
let _ = dotenv();
4441
let database_url =
45-
env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
42+
dotenv::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set to run tests");
4643
let conn = PgConnection::establish(&database_url).unwrap();
4744
conn.begin_test_transaction().unwrap();
4845
conn

src/tests/util.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ pub struct TestApp(Rc<TestAppInner>);
4848
impl TestApp {
4949
/// Initialize an application with an `Uploader` that panics
5050
pub fn init() -> TestAppBuilder {
51-
dotenv::dotenv().ok();
5251
let (app, middle) = crate::simple_app(Uploader::Panic);
5352
let inner = Rc::new(TestAppInner {
5453
app,

0 commit comments

Comments
 (0)