У меня возникли проблемы с запуском веб-сервера Salvo+rustls внутри tokio::spawn. Я получаю ошибку 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;
})
}
Ошибка, которую я получаю
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)
Лучшее, что я смог найти, это проблема с Rust здесь https://github.com/rust-lang/rust/issues/96865 но я не могу придумать правильный синтаксис Rust, чтобы ошибка исчезла.
Удалите Result из уравнения (см. отредактированное содержание). К сожалению, это все еще ошибки.

Вы можете запустить его как локальную задачу в новом потоке. Если вы так сделаете, то ничего не потребуется 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(())
})
})
}
Мне нужно было создать LocalSet и использовать его, но spawn_local, похоже, помогло.
Я не уверен, какой результат находится в модуле ошибок, но проблема должна быть. Я предполагаю, что какой-то вариант сохраняется
runtime::io::registration::Registrationбез времени жизни, поэтому «Отправка» не реализована, и результат также НЕ отправляется.... можете ли вы поделиться результатом?