I'm having issues starting a Salvo+rustls web server inside of a tokio::spawn
. I'm getting the error implementation of 'Send' is not general enough
use std::fs;
use salvo::{
conn::rustls::{Keycert, RustlsConfig},
prelude::*,
};
use tokio::task::JoinHandle;
pub fn start_web_server() -> JoinHandle<()> {
tokio::spawn(async move {
let listener = TcpListener::new("0.0.0.0:7878");
let cert_bytes = fs::read("server.crt").unwrap();
let key_bytes = fs::read("server.key").unwrap();
let rustls_config = RustlsConfig::new(Keycert::new().cert(cert_bytes).key(key_bytes));
let acceptor = listener.rustls(rustls_config).bind().await;
let router = Router::new();
Server::new(acceptor).serve(router).await;
})
}
The error I'm getting
error: implementation of `Send` is not general enough
--> crates/core/src/web_server.rs:10:5
|
10 | / tokio::spawn(async move {
11 | | let listener = TcpListener::new("0.0.0.0:7878");
12 | | let cert_bytes = fs::read("server.crt").unwrap();
13 | | let key_bytes = fs::read("server.key").unwrap();
... |
17 | | Server::new(acceptor).serve(router).await;
18 | | })
| |______^ implementation of `Send` is not general enough
|
= note: `Send` would have to be implemented for the type `&runtime::io::registration::Registration`
= note: ...but `Send` is actually implemented for the type `&'0 runtime::io::registration::Registration`, for some specific lifetime `'0`
> rustc --version
rustc 1.80.1 (3f5fd8dd4 2024-08-06)
The best I could find is an issue is Rust here https://github.com/rust-lang/rust/issues/96865 but I can't figure out the right Rust syntax to make the error go away.
You can run it as local task in new thread. If you do so, then nothing will require Send
.
use std::fs;
use crate::error::Result;
use salvo::{
conn::rustls::{Keycert, RustlsConfig},
prelude::*,
};
use tokio::task::JoinHandle;
pub fn start_web_server() -> JoinHandle<Result<()>> {
std::thread::spawn(|| {
tokio::task::spawn_local(async move {
let listener = TcpListener::new("0.0.0.0:7878");
let cert_bytes = fs::read("server.crt")?;
let key_bytes = fs::read("server.key")?;
let rustls_config = RustlsConfig::new(Keycert::new().cert(cert_bytes).key(key_bytes));
let acceptor = listener.rustls(rustls_config).bind().await;
let router = Router::new();
Server::new(acceptor).serve(router).await;
Ok(())
})
})
}