I was experimenting with the async_trait crate and stumble upon the following error:
future created by async block is not Send
by the following code:
#[async_trait::async_trait]
trait DatabaseManagerGetConnection {
async fn get_connection(&self) -> Option<()>;
}
#[async_trait::async_trait]
trait EntityRepositoryExecute {
async fn execute (&self) -> Option<()>;
}
trait TableMapperToEntity {
fn to_entity(&self) -> Option<()>;
}
struct DatabaseManager {
sqlx_db_pool: sqlx::Pool<sqlx::Postgres>
}
#[async_trait::async_trait]
impl DatabaseManagerGetConnection for DatabaseManager {
async fn get_connection(&self) -> Option<()> {
Some(())
}
}
struct EntityRepository <D: DatabaseManagerGetConnection>{
database_manager: std::sync::Arc<D>
}
#[async_trait::async_trait]
// impl <D: DatabaseManagerGetConnection + Send + Sync> EntityRepositoryExecute for EntityRepository<D> {
impl <D: DatabaseManagerGetConnection> EntityRepositoryExecute for EntityRepository<D> {
async fn execute(&self) -> Option<()>{
self.database_manager.get_connection().await.unwrap();
Some(())
}
}
fn main() {
}
After a couple hours trying to understand the issue I tried to swap Line 32
impl <D: DatabaseManagerGetConnection> EntityRepositoryExecute for EntityRepository<D> {
with line Line 31:
impl <D: DatabaseManagerGetConnection + Send + Sync> EntityRepositoryExecute for EntityRepository<D> {
and the error went way. But I still confused on:
- why I would need to add
SendandSynctrait to theD: DatabaseManagerGetConnection?- My understanding was that
async_trait::async_traitmacro was already adding these "guarantees" (traits) to theDatabaseManagerGetConnectiontrait return itself.
- My understanding was that
- As far as I am aware:
ArcimplementsSend + Sync- and
sqlx::Pool<sqlx::Postgres>also implementsSend + Sync
What am I missing?