Diesel: can't send PooledConnection reference

Created on 28 Nov 2019  路  3Comments  路  Source: diesel-rs/diesel

I'm trying to wrap PooledConnection in the Mutex and getting this:

`std::ptr::NonNull<pq_sys::pg_conn>` cannot be shared between threads safely
within `r2d2::PooledConnection<embedded_migrations::diesel::r2d2::ConnectionManager<embedded_migrations::diesel::PgConnection>>`, the trait `std::marker::Sync` is not implemented for `std::ptr::NonNull<pq_sys::pg_conn>`
required because it appears within the type `embedded_migrations::diesel::pg::connection::raw::RawConnection`
required because it appears within the type `embedded_migrations::diesel::PgConnection`
required because it appears within the type `r2d2::Conn<embedded_migrations::diesel::PgConnection>`
required because it appears within the type `std::option::Option<r2d2::Conn<embedded_migrations::diesel::PgConnection>>`
required because it appears within the type `r2d2::PooledConnection<embedded_migrations::diesel::r2d2::ConnectionManager<embedded_migrations::diesel::PgConnection>>`
required because of the requirements on the impl of `std::marker::Send` for `&r2d2::PooledConnection<embedded_migrations::diesel::r2d2::ConnectionManager<embedded_migrations::diesel::PgConnection>>`
required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<&r2d2::PooledConnection<embedded_migrations::diesel::r2d2::ConnectionManager<embedded_migrations::diesel::PgConnection>>>`

Apparently I can't pass reference to a connection?

Most helpful comment

For anyone else running into this: what you probably want to do is to share a Pool instead of PooledConnection, and then call get() from within the thread.

Example 1

async fn execute(pool: &Pool<ConnectionManager<PgConnection>>, data: SomeData) -> Result<(), Error> {
    diesel::insert_into(some_table)
        .values(data)
        .execute(&pool.get()?)?;

    Ok(())
}

Example 2

pub struct Database {
    pool: Pool<ConnectionManager<PgConnection>>,
}

impl Database {
    async fn insert_some_data(&self, data: SomeData) -> Result<(), Error> {
        diesel::insert_into(some_table)
            .values(data)
            .execute(&self.conn.get()?)?;

        Ok(())
    }
}

See r2d2 docs for more: https://docs.diesel.rs/r2d2/

All 3 comments

That's by "design". The underlying connection is just not threadsafe, so it cannot be shared between threads.

For anyone else running into this: what you probably want to do is to share a Pool instead of PooledConnection, and then call get() from within the thread.

Example 1

async fn execute(pool: &Pool<ConnectionManager<PgConnection>>, data: SomeData) -> Result<(), Error> {
    diesel::insert_into(some_table)
        .values(data)
        .execute(&pool.get()?)?;

    Ok(())
}

Example 2

pub struct Database {
    pool: Pool<ConnectionManager<PgConnection>>,
}

impl Database {
    async fn insert_some_data(&self, data: SomeData) -> Result<(), Error> {
        diesel::insert_into(some_table)
            .values(data)
            .execute(&self.conn.get()?)?;

        Ok(())
    }
}

See r2d2 docs for more: https://docs.diesel.rs/r2d2/

For anyone else running into this: what you _probably_ want to do is to share a Pool instead of PooledConnection, and then call get() from within the thread.

Example 1

async fn execute(pool: &Pool<ConnectionManager<PgConnection>>, data: SomeData) -> Result<(), Error> {
    diesel::insert_into(some_table)
        .values(data)
        .execute(&pool.get()?)?;

    Ok(())
}

Example 2

pub struct Database {
    pool: Pool<ConnectionManager<PgConnection>>,
}

impl Database {
    async fn insert_some_data(&self, data: SomeData) -> Result<(), Error> {
        diesel::insert_into(some_table)
            .values(data)
            .execute(&self.conn.get()?)?;

        Ok(())
    }
}

See r2d2 docs for more: https://docs.diesel.rs/r2d2/

thanks for the &pool.get()

Was this page helpful?
0 / 5 - 0 ratings