When is it appropriate to implement Send + Sync for static dispatch

682 Views Asked by At

I find myself playing around with warp.

I would like to pass a database Trait to a warp::Filter using static dispatch, such that the concrete database may vary.

I read that Send + Sync are unsafe to implement, but I don't fully understand when it is appropriate to implement them.

Is it sound to implement Send + Sync in this context:

use std::sync::{Arc, RwLock};

use warp::Filter;
use warp::reply::{json};
use serde_json::{Value};


pub trait IDatabase {
    fn db_read(&self) -> Value;
    fn db_write(&self, data: Value);
}

pub fn get_api_v0_test<T: IDatabase + Send + Sync>(
    db: Arc<RwLock<T>>
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
    warp::path!("api" / "v0" / "test")
        .and(warp::get())
        .map(move || {
            json(&db.read().unwrap().db_read())
        })
}

Edit:

Yes, this example is completely sound!

As @trentcl and @Masklinn pointed out, I am in fact not implementing Send + Sync, I am simply requiring that any type T passed into the filter, implements the Send + Sync Traits, which is completely safe Rust.

1

There are 1 best solutions below

4
On

I read that Send + Sync are unsafe to implement, but I don't fully understand when it is appropriate to implement them.

Because Send and Sync are automatically derived, it is only appropriate to derive them explicitely when wrapping raw pointers, usually because you're wrapping a native library, and after having made sure that the trait is appropriate for the underlying type.

Is it sound to implement Send + Sync in this context:

I don't understand what you'd want to "implement Send + Sync" on in this context.

pub trait IDatabase {

Rust is not C#, IWhatever is not a thing.