如何防止 BB8 连接在多次重复后断开

How do I prevent BB8 connections to break after several repeats

我有一个应用程序应该为所有请求使用共享连接池。我观察到在看似随机的时间,请求失败并显示错误类型 "Closed"。我已将此行为隔离到以下示例中:

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% 的测试之一将在以后的迭代中失败,输出类似于以下内容:

Perform repeat 8782 of UPDATE foo SET a = 81 WHERE id = 1919 RETURNING b ok: Error { kind: Closed, cause: None } thread 'test::much_update_traffic' panicked at 'Perform repeat 8782 of UPDATE foo SET a = 81 WHERE id = 1919 RETURNING b ok: Error { kind: Closed, cause: None }', src\main.rs:44:23

事实证明,问题完全取决于 [tokio::test] 注释,无论何时执行测试都会启动一个不同的运行时。惰性静态使用这些运行时之一进行初始化,一旦该运行时关闭,池就会被销毁。只要生成测试仍在运行,其他测试(具有不同的运行时)就可以使用该值,但一旦关闭就会遇到无效状态。