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?
4 posts - 3 participants

