weldsorm / welds

BSD 3-Clause "New" or "Revised" License
119 stars 6 forks source link

Regression - Unable to spawn tasks using welds with Tokio RT #21

Closed NexRX closed 7 months ago

NexRX commented 7 months ago

Hi all, I'm experiencing a regression of https://github.com/weldsorm/welds/issues/15 after migrating from 0.2 to 0.3

Here is a minimal function that will reproduce and fail to compile

// Or any DbState<T> 
pub async fn create(mut user: DbState<User>, pool: &PostgresClient) {
   let pool = pool.clone();
   tokio::spawn(async move { user.save(&pool).await });
}

error:

`dyn welds_connections::Client` cannot be shared between threads safely
the trait `std::marker::Sync` is not implemented for `dyn welds_connections::Client`
required for `&dyn welds_connections::Client` to implement `std::marker::Send`
required because it captures the following types: `welds::state::DbState<User>`, `impl std::future::Future<Output = std::result::Result<(), _>>`

I'm busy otherwise I'd look into fixing it myself. Thanks for the 0.3 update though! :D

lex148 commented 7 months ago

Thank you so much for reporting this one. I will get it fixed up right away.

lex148 commented 7 months ago

This was important enough to get a patch release out. fixed in 0.3.1

here is the code I was testing with.

use welds::connections::postgres::PostgresClient;
use welds::errors::Result;
use welds::migrations::{create_table, types::Type, up, MigrationStep, TableState};
use welds::prelude::*;

fn create_test_user_table(_state: &TableState) -> Result<MigrationStep> {
    let m = create_table("users")
        .id(|c| c("id", Type::Int))
        .column(|c| c("name", Type::String));
    Ok(MigrationStep::new("create users table", m))
}

#[derive(Debug, WeldsModel)]
#[welds(table = "users")]
pub struct User {
    #[welds(primary_key)]
    pub id: i32,
    pub name: String,
}

#[tokio::main]
async fn main() -> Result<()> {
    env_logger::init();
    let url = "postgres://postgres:password@localhost";
    let client = welds::connections::postgres::connect(url).await?;

    // Make the users table if it doesn't exist
    up(&client, &[create_test_user_table]).await?;

    let user = User::new();
    create(user, &client).await;

    let count: u64 = User::all().count(&client).await?;
    println!("COUNT: {}", count);

    Ok(())
}

pub async fn create(mut user: DbState<User>, pool: &PostgresClient) {
    let pool = pool.clone();
    tokio::spawn(async move { user.save(&pool).await }).await;
}
lex148 commented 7 months ago

I am going to go ahead and mark this as closed. if you are still having any issues please let me know.

NexRX commented 7 months ago

Awesome fast work @lex148 ! Thanks for getting that out there!