Cannot use struct's member variable in a tokio::spawn function

I implement a gRPC server which streams data to its client. I want the server to start sending back data on the event of another module via a "channel notifer".

To illustrate the main point, I simplify the implementation to a "hello" server. The gRPC proto file is:

syntax = "proto3";

package hello;

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

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

And the rs file is simple:

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(())
}

I create a pair of channel endpoint in the main, and then use the receiver endpoint as a notifer in gRPC server. The send endpoint is assigned to another module which is omitted in this code for sending new generated data.

I know this error must be related to the ownership of Rust. I have tried to wrap the channel endpoint in Arc<T> and protected by a Mutex<T>. However, it doesn't work.

You are trying to build what is a very simple actor that receives a single message. Please read this post on how to write actors that are approved by the borrow-checker. The main idea is to split your struct into two structs.

Also, you need to think about what happens when there are more than one call to say_hello. Your channel is a single-consumer channel, so you can't have multiple tasks receiving from it at the same time.

Your post saves me a lot. It seem Rust has some implicit "Rules" or "Design Patterns" that are different from traditional languages. I will appreciate if some docs or blogs you can provides on this topic.

Typically when Rust disallows some pattern, it's because it violates the single-ownership rule, or otherwise shares something in an invalid way.