future cannot be sent between threads safely

148 Views Asked by At

I want to implement jwt via from_request, but an error occurs that says that Send is not implemented. Whereas, if you remove the trait implementation for the structure, the error disappears (i.e.: impl CryptoService)

use actix_web::{FromRequest, HttpResponse, ResponseError};
use actix_web::http::StatusCode;
use actix_web::web::Data;
use async_trait::async_trait;
use derive_more::Display;
use futures::future::BoxFuture;

pub struct CryptoService {}

#[async_trait(?Send)]
pub trait CryptoServiceAbstract {
    async fn verify_jwt(&self);
}

#[async_trait(?Send)]
impl CryptoServiceAbstract for CryptoService {
    async fn verify_jwt(&self) {
        todo!()
    }
}

#[derive(Debug, Display)]
pub struct ErrorReponse {}

impl ResponseError for ErrorReponse {
    fn status_code(&self) -> StatusCode {
        todo!()
    }

    fn error_response(&self) -> HttpResponse {
        todo!()
    }
}

pub struct AuthenticatedUser {}

impl FromRequest for AuthenticatedUser {
    type Error = ErrorReponse;
    type Future = BoxFuture<'static, Result<Self, Self::Error>>;

    fn from_request(req: &actix_web::HttpRequest, payload: &mut actix_web::dev::Payload) -> Self::Future {
        let crypto_service_result = Data::<CryptoService>::from_request(req, payload).into_inner();

        match crypto_service_result {
            Ok(crypto_service) => {
                let future = async move {

                    crypto_service.verify_jwt().await;

                    Ok(AuthenticatedUser {})
                };

                Box::pin(future)
            }
            _ => {
                todo!()
            }
        }
    }
}

an error

error: future cannot be sent between threads safely
  --> src\second_main.rs:53:17
   |
53 |                 Box::pin(future)
   |                 ^^^^^^^^^^^^^^^^ future created by async block is not `Send`
   |
   = help: the trait `std::marker::Send` is not implemented for `dyn futures::Future<Output = ()>`
note: future is not `Send` as it awaits another future which is not `Send`
  --> src\second_main.rs:48:21
   |
48 |                     crypto_service.verify_jwt().await;
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `Pin<Box<dyn futures::Future<Output = ()>>>`, which is not `Send`
   = note: required for the cast from `Pin<Box<{async block@src\second_main.rs:46:30: 51:18}>>` to `Pin<Box<dyn futures::Future<Output = Result<AuthenticatedUser, ErrorReponse>> + std::marker::Send>>`
[dependencies]
actix-web = "4.4.1"
derive_more = "0.99.17"
futures = "0.3.30"
async-trait = "0.1.77"

The error is due to the implementation of the feature, I thought that it was necessary to connect some functions, but I did not find anything. I also deleted all the unnecessary parts, but I still don't understand what the problem might be.

1

There are 1 best solutions below

0
Vlad On

I solved the problem by updating the Rust version from 1.74.1 to 1.75, which made it possible to use async fn in traits. I still don't understand why this didn't work for create async_trait. But now I just gave up using this crate and everything worked.

pub trait CryptoServiceAbstract {
    async fn verify_jwt(&self);
}

impl CryptoServiceAbstract for CryptoService {
    async fn verify_jwt(&self) {
        todo!()
    }
}