不能在 tokio::spawn 函数中使用结构的成员变量

问题描述

我实现了一个 gRPC 服务器,它将数据流式传输到其客户端。我希望服务器通过“通道通知程序”开始发送有关另一个模块事件的数据。

为了说明要点,我将实现简化为“hello”服务器。 gRPC proto 文件是:

Syntax = "proto3";

package hello;

service Greeter {
    rpc SayHello (HelloRequest) returns (stream HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

rs 文件很简单:

pub mod hello_world {
    tonic::include_proto!("hello");
}

// This is my server's implementation.
pub struct MyGreeter {
    // The new data is sent over to gRPC server via this mpsc::Receiver channel.
    notifer: mpsc::Receiver<i32>,}


#[tonic::async_trait]
impl Greeter for MyGreeter {

    type SayHelloStream = ReceiverStream<Result<HelloReply,Status>>;

    async fn say_hello(
        &self,request: Request<HelloRequest>,) -> Result<Response<Self::SayHelloStream>,Status> {
        println!("Got a request from {:?}",request.remote_addr());

        // compiling error here: this data with lifetime `'life0`...
        let (api_tx,api_rx) = mpsc::channel(3);

        tokio::spawn(async move {

            // compiling error here: ...and is required to live as long as `'static` here
            self.notifer.recv().await.unwrap();

            api_tx.send(Ok(HelloReply {
                message: format!("Hello {}!",request.into_inner().name),})).await.unwrap();
        });

        Ok(Response::new(ReceiverStream::new(api_rx)))
    }
}

#[tokio::main]
async fn main() -> Result<(),Box<dyn std::error::Error>> {
    let addr = "[::1]:50051".parse().unwrap();

    // Create a pair of channel endpoint
    // tx is used somewhere for sending new data.
    let (tx,rx) = mpsc::channel(3);

    let greeter = MyGreeter {
        // the receiver endpoint
        notifer: rx,};

    println!("GreeterServer listening on {}",addr);

    Server::builder()
        .add_service(GreeterServer::new(greeter))
        .serve(addr)
        .await?;

    Ok(())
}

我在 main 中创建了一对通道端点,然后在 gRPC 服务器中使用接收器端点作为通知器。发送端点被分配给另一个模块,此代码在发送新生成的数据时省略了该模块。

我知道这个错误一定与 Rust 的 ownership 有关。我尝试将通道端点包装在 Arc<T> 中并受 Mutex<T> 保护。但是,它不起作用。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)