I'm building an API using Rocket and Diesel, and I'm managing the DbPool using Rocket's State. A search request handler might look like this, then:
#[get("/search?<term>")]
pub fn general_privileged(
db_pool: &State<Pool>,
_key: PrivilegedApiKey,
term: &str,
) -> Json<Vec<SearchResult>> {
let dao1_connection = db_pool.get().unwrap();
let dao2_connection = db_pool.get().unwrap();
let company_dao = CompanyDao::new(dao1_connection);
let user_dao = UserDao::new(dao2_connection);
let results = lib::search::general_privileged::search(term, company_dao, user_dao);
Json(results)
}
As you can see, I'm unwrapping the connections here, which is not a good practice. In the case of a panic, it takes the service a long time to recover, which degrades performance. Obviously I could just return a `503 status instead of panicking (better!) but that's still not a great experience to have an API that frequently cannot talk to the DB.
I could use some help understanding a few things here:
- Under what circumstances should I expect a failure to retrieve a connection from the pool; i.e. can I plan for and avoid these situations?
- What are the recommended best practices for handling such failures?
- What are the recommended best practices for responding to and recovering from such failures?