Help: the trait `std::marker::Send` is not implemented for `dyn Future<Output = Result<Option<Vec<u8>>, Error>>`

I want to put asynchronous methods into a map and trigger different methods with different keys, but now it prompts me that the returned results cannot be safely passed in the thread. How should I handle this

pub type Result<T, E = error::Error> = std::result::Result<T, E>;

#[derive(thiserror::Error, Debug)]
pub enum Error {
 
    /// Return `404 Not Found`
    #[error("request path not found")]
    NotFound,

    #[error("an error occurred with the database")]
    Sqlx(#[from] sqlx::Error),
    
    #[error("an error occurred with the hyper")]
    Hyper(#[from] hyper::Error),

    #[error("an error occurred with the Protobuf")]
    Protobuf(#[from] protobuf::Error),
    
    #[error("std io error")]
    Io(#[from] std::io::Error),
}


type Handler = Box<
    dyn Fn(Arc<String>, Option<Vec<u8>>) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>>>>
        + Send
        + Sync,
>;


static HANDLERS_MAP: OnceLock<HashMap<u8, Handler>> = OnceLock::new();



pub async fn accept(uid: Arc<String>, data: Option<Vec<u8>>) -> Result<Option<Vec<u8>>> {}
pub async fn send(uid: Arc<String>, data: Option<Vec<u8>>) -> Result<Option<Vec<u8>>> {}

What does rustc tell?

Try adding the bound to the trait object type, changing dyn Future<…> to dyn Future<…> + Send.


Also make sure to post more complete error messages if possible - if your IDE doesn't show them, or you don't know where to get the full message, consider running cargo check on the terminal to get the full error message ^^

3 Likes

not work, When I change the 'E' in 'Result<T,E>' to 'Box<dyn std::error::Error + Send + Sync>', it works properly

error: future cannot be sent between threads safely                                                                                                                                
   --> src\handler\mod.rs:47:13
    |
47  |             friend_requests::send(uid, bytes).boxed()
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `send` is not `Send`
    |
    = help: within `impl futures_util::Future<Output = std::result::Result<std::option::Option<Vec<u8>>, common::error::Error>>`, the trait `std::marker::Send` is not implemented for `*const seize::raw::collector::Reservation`
note: future is not `Send` as this value is used across an await
   --> src\handler\mod.rs:187:54
    |
186 |             if let Some(sender) = SENDER_MAP.pin().get(&session.cid) {
    |                                   ---------------- has type `HashMapRef<'_, Arc<std::string::String>, tokio::sync::mpsc::Sender<CccpMessage>, RandomState, LocalGuard<'_>>` which is not `Send`
187 |                 publish(ty, content.clone(), sender).await;
    |                                                      ^^^^^ await occurs here, with `SENDER_MAP.pin()` maybe used later
note: required by a bound in `moka::future::FutureExt::boxed`
   --> C:\Users\LSHM\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\moka-0.12.10\src\future.rs:49:44
    |
47  |     fn boxed<'a, T>(self) -> BoxFuture<'a, T>
    |        ----- required by a bound in this associated function
48  |     where
49  |         Self: Future<Output = T> + Sized + Send + 'a,
    |                                            ^^^^ required by this bound in `FutureExt::boxed`

error: future cannot be sent between threads safely
   --> src\handler\mod.rs:47:13
    |
47  |             friend_requests::send(uid, bytes).boxed()
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `send` is not `Send`
    |
    = help: within `impl futures_util::Future<Output = std::result::Result<std::option::Option<Vec<u8>>, common::error::Error>>`, the trait `std::marker::Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await
   --> src\handler\mod.rs:187:54
    |
186 |             if let Some(sender) = SENDER_MAP.pin().get(&session.cid) {
    |                                   ---------------- has type `HashMapRef<'_, Arc<std::string::String>, tokio::sync::mpsc::Sender<CccpMessage>, RandomState, LocalGuard<'_>>` which is not `Send`
187 |                 publish(ty, content.clone(), sender).await;
    |                                                      ^^^^^ await occurs here, with `SENDER_MAP.pin()` maybe used later
note: required by a bound in `moka::future::FutureExt::boxed`
   --> C:\Users\LSHM\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\moka-0.12.10\src\future.rs:49:44
    |
47  |     fn boxed<'a, T>(self) -> BoxFuture<'a, T>
    |        ----- required by a bound in this associated function
48  |     where
49  |         Self: Future<Output = T> + Sized + Send + 'a,
    |                                            ^^^^ required by this bound in `FutureExt::boxed`

error: future cannot be sent between threads safely                                                                                                                                
   --> src\net\acceptor.rs:13:9
    |
13  | /         tokio::spawn(async move {
14  | |             process(stream).await;
15  | |         });
    | |__________^ future created by async block is not `Send`
    |
    = help: within `{async block@src\net\acceptor.rs:13:22: 13:32}`, the trait `std::marker::Send` is not implemented for `*const seize::raw::collector::Reservation`
note: future is not `Send` as this value is used across an await
   --> src\handler\mod.rs:75:29
    |
74  |     if let Some(handler) = handlers_map.pin().get(&task_type) {
    |                            ------------------ has type `HashMapRef<'_, u8, Box<dyn Fn(Arc<std::string::String>, std::option::Option<Vec<u8>>) -> Pin<Box<dyn futures_util::Future<Output = std::result::Result<std::option::Option<Vec<u8>>, common::error::Error>>>> + std::marker::Send + Sync>, RandomState, LocalGuard<'_>>` which is not `Send`
75  |         handler(uid, bytes).await
    |                             ^^^^^ await occurs here, with `handlers_map.pin()` maybe used later
note: required by a bound in `tokio::spawn`
   --> C:\Users\LSHM\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\tokio-1.44.2\src\task\spawn.rs:168:21
    |
166 |     pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
    |            ----- required by a bound in this function
167 |     where
168 |         F: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

error: future cannot be sent between threads safely
   --> src\net\acceptor.rs:13:9
    |
13  | /         tokio::spawn(async move {
14  | |             process(stream).await;
15  | |         });
    | |__________^ future created by async block is not `Send`
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn futures_util::Future<Output = std::result::Result<std::option::Option<Vec<u8>>, common::error::Error>>`       
note: future is not `Send` as it awaits another future which is not `Send`
   --> src\handler\mod.rs:75:9
    |
75  |         handler(uid, bytes).await
    |         ^^^^^^^^^^^^^^^^^^^ await occurs here on type `Pin<Box<dyn futures_util::Future<Output = std::result::Result<std::option::Option<Vec<u8>>, common::error::Error>>>>`, which is not `Send`
note: required by a bound in `tokio::spawn`
   --> C:\Users\LSHM\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\tokio-1.44.2\src\task\spawn.rs:168:21
    |
166 |     pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
    |            ----- required by a bound in this function
167 |     where
168 |         F: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

error: future cannot be sent between threads safely
   --> src\net\acceptor.rs:13:9
    |
13  | /         tokio::spawn(async move {
14  | |             process(stream).await;
15  | |         });
    | |__________^ future created by async block is not `Send`
    |
    = help: within `{async block@src\net\acceptor.rs:13:22: 13:32}`, the trait `std::marker::Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await
   --> src\handler\mod.rs:75:29
    |
74  |     if let Some(handler) = handlers_map.pin().get(&task_type) {
    |                            ------------------ has type `HashMapRef<'_, u8, Box<dyn Fn(Arc<std::string::String>, std::option::Option<Vec<u8>>) -> Pin<Box<dyn futures_util::Future<Output = std::result::Result<std::option::Option<Vec<u8>>, common::error::Error>>>> + std::marker::Send + Sync>, RandomState, LocalGuard<'_>>` which is not `Send`
75  |         handler(uid, bytes).await
    |                             ^^^^^ await occurs here, with `handlers_map.pin()` maybe used later
note: required by a bound in `tokio::spawn`
   --> C:\Users\LSHM\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\tokio-1.44.2\src\task\spawn.rs:168:21
    |
166 |     pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
    |            ----- required by a bound in this function
167 |     where
168 |         F: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

Thank you all.I solved this problem,
type Handler = Box<
dyn Fn(Arc, Option<Vec>) -> Box<dyn Future<Output = Result<Option<Vec>>>>>
to type Handler = Box<dyn Fn(Arc, Option<Vec>) -> BoxFuture<'static, Result<Option<Vec>>> + Send + Sync>;

Will this approach have performance issues compared to direct invocation

By the way, please make sure to check out this topic on how to mark code blocks correctly


If you don’t mark code section, it can lead to confusing display, as e.g.

•  indentation/spacing is not preserved (click to expand)

for example the code

fn foobar() {
    println!("hello       world!");
}

looks like this without the code block:

fn foobar() {
println!("hello world!");
}

•  HTML-like syntax can be interpreted as HTML and then rendered as such, or discarded if disallowed (click to expand)

for example the code

fn my_function<Generic>() {
    let pi = 3.14;
    let reference = &pi;
}

looks like this without the code block:

fn my_function() {
let pi = 3.14;
let reference = π
}

This issue even applies to short inline mentions of types such as “Vec<u8>” being presented as “Vec” unfortunately, when you don’t wrap it in `s like “`Vec<u8>`”[1] :wink:

And the above paragraph itself can be created like this… (click to expand)
This issue even applies to short inline mentions of types such as “`Vec<u8>`” being presented as “Vec<u8>” unfortunately, when you don’t wrap it in `` ` ``s like “`` `Vec<u8>` ``”^[or HTML like `<code>Vec&lt;u8></code>` can work, too<br>there is also escaping such as <code>\<code>Vec\\\<u8>\</code></code><br><br>Both of these display as <code>Vec\<u8></code>…<br>…if you *only* escape, like `Vec\<u8>`, you at least get “Vec\<u8>”] :wink:

In some of your previous posts, I have already fixed the issue for you.


  1. or HTML like <code>Vec&lt;u8></code> can work, too
    there is also escaping such as <code>Vec\<u8></code>

    Both of these display as Vec<u8>…
    …if you only escape, like Vec\<u8>, you at least get “Vec<u8>” ↩︎