为什么我不能使用 Rust tonic 并行发送多个请求?
Why can't I send multiple requests in parallel using rust tonic?
我实施了补品 helloworld 教程。然后我尝试更改客户端代码,以便在等待任何请求之前发送多个请求。
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let num_requests = 10;
let mut client = GreeterClient::connect("http://[::1]:50051").await?;
let mut responses = Vec::with_capacity(num_requests);
for _ in 0..num_requests {
let request = tonic::Request::new(HelloRequest {
name: "Tonic".into(),
});
responses.push(client.say_hello(request));
}
for resp in responses {
assert!(resp.await.is_ok());
}
Ok(())
}
这会导致编译错误:
error[E0499]: cannot borrow `client` as mutable more than once at a time
--> src/client.rs:19:24
|
19 | responses.push(client.say_hello(request));
| ^^^^^^ mutable borrow starts here in previous iteration of loop
这是否意味着 'client.say_hello()' returns 仍然引用客户端的类型,因此我无法再次调用 'say_hello',它本身需要“&mut self”?有没有办法在调用'await'之前继续发出请求?
Sending a request on a channel requires a &mut self
and thus can only send one request in flight. This is intentional and is required to follow the Service
contract from the tower
library which this channel implementation is built on top of.
...
To work around this and to ease the use of the channel, Channel
provides a Clone
implementation that is cheap. This is because at the very top level the channel is backed by a tower_buffer::Buffer
which runs the connection in a background task and provides a mpsc
channel interface. Due to this cloning the Channel
type is cheap and encouraged.
因此,您可以为您发出的每个并发请求克隆客户端。这消除了单个客户端在任何给定时间被多次借用的可能性,因此借用检查器得到安抚。
let num_requests = 10;
let client = GreeterClient::connect("http://[::1]:50051").await?;
let mut responses = Vec::with_capacity(num_requests);
for _ in 0..num_requests {
let mut client = client.clone();
let request = tonic::Request::new(HelloRequest {
name: "Tonic".into(),
});
responses.push(tokio::spawn(async move {
client.say_hello(request).await
}));
}
for resp in responses {
let resp = resp.await;
assert!(resp.is_ok());
assert!(resp.unwrap().is_ok());
}
我实施了补品 helloworld 教程。然后我尝试更改客户端代码,以便在等待任何请求之前发送多个请求。
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let num_requests = 10;
let mut client = GreeterClient::connect("http://[::1]:50051").await?;
let mut responses = Vec::with_capacity(num_requests);
for _ in 0..num_requests {
let request = tonic::Request::new(HelloRequest {
name: "Tonic".into(),
});
responses.push(client.say_hello(request));
}
for resp in responses {
assert!(resp.await.is_ok());
}
Ok(())
}
这会导致编译错误:
error[E0499]: cannot borrow `client` as mutable more than once at a time
--> src/client.rs:19:24
|
19 | responses.push(client.say_hello(request));
| ^^^^^^ mutable borrow starts here in previous iteration of loop
这是否意味着 'client.say_hello()' returns 仍然引用客户端的类型,因此我无法再次调用 'say_hello',它本身需要“&mut self”?有没有办法在调用'await'之前继续发出请求?
Sending a request on a channel requires a
&mut self
and thus can only send one request in flight. This is intentional and is required to follow theService
contract from thetower
library which this channel implementation is built on top of.
...
To work around this and to ease the use of the channel,Channel
provides aClone
implementation that is cheap. This is because at the very top level the channel is backed by atower_buffer::Buffer
which runs the connection in a background task and provides ampsc
channel interface. Due to this cloning theChannel
type is cheap and encouraged.
因此,您可以为您发出的每个并发请求克隆客户端。这消除了单个客户端在任何给定时间被多次借用的可能性,因此借用检查器得到安抚。
let num_requests = 10;
let client = GreeterClient::connect("http://[::1]:50051").await?;
let mut responses = Vec::with_capacity(num_requests);
for _ in 0..num_requests {
let mut client = client.clone();
let request = tonic::Request::new(HelloRequest {
name: "Tonic".into(),
});
responses.push(tokio::spawn(async move {
client.say_hello(request).await
}));
}
for resp in responses {
let resp = resp.await;
assert!(resp.is_ok());
assert!(resp.unwrap().is_ok());
}