web::block() 失败并显示“`NonNull<pq_sys::pg_conn>` 无法在线程间安全共享”

web::block() fails with "`NonNull<pq_sys::pg_conn>` cannot be shared between threads safely"

#[macro_use]
extern crate diesel;

use diesel::result::Error;

use actix_web::web;
use diesel::{PgConnection, QueryDsl, RunQueryDsl};
use r2d2::{Pool, PooledConnection};
use r2d2_diesel::ConnectionManager;
use schema::tests::dsl::*;

pub mod schema;

pub type MyDBConnectionManager = ConnectionManager<PgConnection>;
pub type MyPool = Pool<MyDBConnectionManager>;
pub type MyDBConnection = PooledConnection<MyDBConnectionManager>;

struct S { }

impl S {
    async fn download_and_store_object(pool: web::Data<MyPool>) -> Result<(), Error>
    {
        let conn_ = pool.get().expect("couldn't get db connection from pool");
        let conn = &conn_;

        let v_data_size: Option<i64> = web::block(move || -> Result<_, Error> {
            Ok(tests.select(b).get_result::<Option<i64>>(&**conn)?)
        }).await.unwrap();

        Ok(())

    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    Ok(())
}
`NonNull<pq_sys::pg_conn>` cannot be shared between threads safely
within `PooledConnection<ConnectionManager<PgConnection>>`, the trait `Sync` is not implemented for `NonNull<pq_sys::pg_conn>`
required because of the requirements on the impl of `std::marker::Send` for `&PooledConnection<ConnectionManager<PgConnection>>`
required because it appears within the type `[closure@src/main.rs:26:51: 28:10]`rustcE0277

架构:

table! {
    tests (seq) {
        seq -> Int4,
        a -> Nullable<Bytea>,
        b -> Nullable<Int8>,
    }
}

错误是什么?以及如何纠正它?

如评论中所述,Conn 不能在线程之间共享,因此在这种情况下,您需要移动 Pool 句柄,并从 clusure 本身内部获取连接:

#[macro_use]
extern crate diesel;

use diesel::result::Error;

use actix_web::web;
use diesel::{PgConnection, QueryDsl, RunQueryDsl};
use r2d2::{Pool, PooledConnection};
use r2d2_diesel::ConnectionManager;
use schema::tests::dsl::*;

pub mod schema;

pub type MyDBConnectionManager = ConnectionManager<PgConnection>;
pub type MyPool = Pool<MyDBConnectionManager>;
pub type MyDBConnection = PooledConnection<MyDBConnectionManager>;

struct S { }

impl S {
    async fn download_and_store_object(pool: web::Data<MyPool>) -> Result<(), Error>
    {

        let v_data_size: Option<i64> = web::block(move || -> Result<_, Error> {
            let conn = pool.get().expect("couldn't get db connection from pool");

            Ok(tests.select(b).get_result::<Option<i64>>(&conn)?)
        }).await.unwrap();

        Ok(())

    }
}