Реализация Send не является достаточно общей

У меня возникли проблемы с запуском веб-сервера 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, чтобы ошибка исчезла.

Я не уверен, какой результат находится в модуле ошибок, но проблема должна быть. Я предполагаю, что какой-то вариант сохраняется runtime::io::registration::Registration без времени жизни, поэтому «Отправка» не реализована, и результат также НЕ отправляется.... можете ли вы поделиться результатом?

Milan Jaric 01.09.2024 00:35

Удалите Result из уравнения (см. отредактированное содержание). К сожалению, это все еще ошибки.

joegtp 01.09.2024 03:42
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
2
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете запустить его как локальную задачу в новом потоке. Если вы так сделаете, то ничего не потребуется 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, похоже, помогло.

joegtp 01.09.2024 04:51

Другие вопросы по теме