Skip to content

Commit c45d74b

Browse files
1344: Allow database timeouts to be configured r=ashleygwilliams We're consistently seeing the endpoint for crate downloads H12. The logs are showing that we are *eventually* finishing without error, it's just taking >30s, so Heroku is killing the connection. Unfortunately, this means that we don't have visibility into *why* it's timing out. It's either waiting for a long time for a DB connection, updating the `version_downloads` table (my guess), or talking to S3. If it's database related, this will turn those requests into actual errors. This setting will increase our error rates, as we're seeing the 99th percentile push up to 5s at some points, and we do have requests that take 15s to complete (but are completing). Eventually I think we should be able to consider 10s response times unacceptable, but for now I'm only going to leave this at 10s for long enough for me to see *what* is failing, at which point I will set it back to 30s until we no longer see requests pushing 10s regularly.
2 parents 1a3a1c6 + c8c39a9 commit c45d74b

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

src/app.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::env;
44
use std::path::PathBuf;
55
use std::sync::{Arc, Mutex};
6+
use std::time::Duration;
67

78
use diesel::r2d2;
89
use git2;
@@ -71,11 +72,19 @@ impl App {
7172
_ => 1,
7273
};
7374

75+
let db_connection_timeout = match (env::var("DB_TIMEOUT"), config.env) {
76+
(Ok(num), _) => num.parse().expect("couldn't parse DB_TIMEOUT"),
77+
(_, ::Env::Production) => 10,
78+
_ => 30,
79+
};
80+
7481
let thread_pool = Arc::new(ScheduledThreadPool::new(db_helper_threads));
7582

7683
let diesel_db_config = r2d2::Pool::builder()
7784
.max_size(db_pool_size)
7885
.min_idle(db_min_idle)
86+
.connection_timeout(Duration::from_secs(db_connection_timeout))
87+
.connection_customizer(Box::new(db::SetStatementTimeout(db_connection_timeout)))
7988
.thread_pool(thread_pool);
8089

8190
let repo = git2::Repository::open(&config.git_repo_checkout).unwrap();

src/db.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::env;
22

33
use conduit::Request;
4-
use diesel::prelude::{ConnectionResult, PgConnection};
5-
use diesel::r2d2::{self, ConnectionManager};
4+
use diesel::prelude::*;
5+
use diesel::r2d2::{self, ConnectionManager, CustomizeConnection};
66
use url::Url;
77

88
use middleware::app::RequestApp;
@@ -44,3 +44,17 @@ impl<T: Request + ?Sized> RequestTransaction for T {
4444
self.app().diesel_database.get().map_err(Into::into)
4545
}
4646
}
47+
48+
#[derive(Debug, Clone, Copy)]
49+
pub struct SetStatementTimeout(pub u64);
50+
51+
impl CustomizeConnection<PgConnection, r2d2::Error> for SetStatementTimeout {
52+
fn on_acquire(&self, conn: &mut PgConnection) -> Result<(), r2d2::Error> {
53+
use diesel::sql_query;
54+
55+
sql_query(format!("SET statement_timeout = {}", self.0 * 1000))
56+
.execute(conn)
57+
.map_err(r2d2::Error::QueryError)?;
58+
Ok(())
59+
}
60+
}

0 commit comments

Comments
 (0)