backend/db/
connection.rs

1//! Utilities to set up the initial connection to the database.
2
3use diesel_async::{
4    pooled_connection::deadpool, pooled_connection::AsyncDieselConnectionManager, AsyncPgConnection,
5};
6use std::{ops::Deref, thread::available_parallelism};
7
8/// Type renaming of [`deadpool::Pool`] using [`AsyncPgConnection`]
9pub type Pool = deadpool::Pool<AsyncPgConnection>;
10
11/// Holds both connection pools.
12#[derive(Clone)]
13pub struct ConnectionPools {
14    pub fast_pool: Pool,
15    pub slow_pool: Pool,
16}
17
18impl Deref for ConnectionPools {
19    type Target = Pool;
20
21    fn deref(&self) -> &Self::Target {
22        &self.fast_pool
23    }
24}
25
26/// Creates an initialized pool connecting to the database.
27///
28/// # Panics
29/// If the pool is unable to open its minimum number of connections.
30#[must_use]
31pub fn init_pool(url: &str) -> ConnectionPools {
32    let cpu_cores = available_parallelism().map_or_else(
33        |_| panic!("Unable to determine the number of CPU cores"),
34        std::num::NonZero::get,
35    );
36    let per_pool_size = cpu_cores * 2;
37
38    let manager_fast = AsyncDieselConnectionManager::<AsyncPgConnection>::new(url);
39    let manager_slow = AsyncDieselConnectionManager::<AsyncPgConnection>::new(url);
40
41    let fast_pool = deadpool::Pool::builder(manager_fast)
42        .max_size(per_pool_size)
43        .build()
44        .unwrap_or_else(|e| panic!("Error while creating fast pool: {e}"));
45
46    let slow_pool = deadpool::Pool::builder(manager_slow)
47        .max_size(per_pool_size)
48        .build()
49        .unwrap_or_else(|e| panic!("Error while creating slow pool: {e}"));
50
51    ConnectionPools {
52        fast_pool,
53        slow_pool,
54    }
55}