Как предотвратить разрыв соединения BB8 после нескольких повторов - PullRequest
0 голосов
/ 31 марта 2020

У меня есть приложение, которое должно использовать общий пул соединений для всех запросов. Я наблюдаю, что в случайные, на первый взгляд, запросы не выполняются с ошибкой типа «Закрыто». Я выделил это поведение в следующем примере:

use lazy_static::lazy_static;

use bb8_postgres::bb8::Pool;
use bb8_postgres::PostgresConnectionManager;
use bb8_postgres::tokio_postgres::{NoTls, Client};

lazy_static! {
    static ref CONNECTION_POOL: Pool<PostgresConnectionManager<NoTls>> = {
        let manager = PostgresConnectionManager::new_from_stringlike("dbname=demodb host=localhost user=postgres", NoTls).unwrap();

        Pool::builder().build_unchecked(manager)
    };
}

fn main() {
    println!("Hello, world!");
}


#[cfg(test)]
mod test {
    use super::*;

    #[tokio::test]
    async fn much_insert_traffic() {
        much_traffic("INSERT INTO foo(a,b) VALUES (1, 2) RETURNING id").await
    }

    #[tokio::test]
    async fn much_select_traffic() {
        much_traffic("SELECT MAX(id) FROM foo").await
    }

    #[tokio::test]
    async fn much_update_traffic() {
        much_traffic("UPDATE foo SET a = 81 WHERE id = 1919 RETURNING b").await;
    }

    async fn much_traffic(stmt: &str) {
        let c = CONNECTION_POOL.get().await.expect("Get a connection");
        let client = &*c;

        for i in 0..10000i32 {
            let res = client.query_opt(stmt, &[]).await.expect(&format!("Perform repeat {} of {} ok", i, stmt));
        }
    }

}

При выполнении тестов> 50% один из тестов завершится неудачно в более поздней итерации с выводом, подобным следующему:

Выполнить повтор 8782 UPDATE foo SET a = 81 WHERE id = 1919 ВОЗВРАТ b ok: Ошибка {вид: Закрыто, причина: нет} поток 'test :: much_update_traffi c' запанирован в 'Выполнить повтор 8782 UPDATE foo SET a = 81 ГДЕ id = 1919 ВОЗВРАТ b нормально: Ошибка {тип: Закрыто, причина: нет} ', src \ main.rs: 44: 23

1 Ответ

0 голосов
/ 15 апреля 2020

Оказывается, проблема полностью основана на аннотации [tokio::test], запускающей отдельное время выполнения при каждом выполнении теста. Ленивое состояние c инициализируется с одной из этих сред выполнения, и как только эта среда завершается, пул уничтожается. Другие тесты (с разными временами выполнения) могут использовать это значение, пока нерестовый тест все еще выполняется, но встречается с недопустимым состоянием после его закрытия.

...