मैंने टॉनिक 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 ()' एक प्रकार लौटाता है जो अभी भी क्लाइंट को संदर्भित करता है, और इसलिए मैं 'say_hello' को एक और कॉल नहीं कर सकता, जिसके लिए स्वयं को '& mut self' की आवश्यकता होती है? क्या 'प्रतीक्षा' करने के लिए कॉल करने से पहले अनुरोध करना जारी रखने का कोई तरीका है?

2
matanmarkind 23 जिंदा 2021, 23:35

1 उत्तर

सबसे बढ़िया उत्तर

टॉनिक दस्तावेज़ से:

चैनल पर अनुरोध भेजने के लिए &mut self की आवश्यकता होती है और इस प्रकार उड़ान में केवल एक अनुरोध भेजा जा सकता है। यह जानबूझकर है और tower लाइब्रेरी से Service अनुबंध का पालन करने के लिए आवश्यक है, जिसके ऊपर यह चैनल कार्यान्वयन बनाया गया है।
...
इस पर काम करने के लिए और चैनल के उपयोग को आसान बनाने के लिए, Channel एक Clone कार्यान्वयन प्रदान करता है जो कि सस्ता है। ऐसा इसलिए है क्योंकि शीर्ष स्तर पर चैनल एक tower_buffer::Buffer द्वारा समर्थित है जो एक पृष्ठभूमि कार्य में कनेक्शन चलाता है और एक mpsc चैनल इंटरफ़ेस प्रदान करता है। इस क्लोनिंग के कारण Channel प्रकार सस्ता और प्रोत्साहित होता है।

इसलिए, आप अपने द्वारा किए गए प्रत्येक समवर्ती अनुरोध के लिए क्लाइंट को क्लोन कर सकते हैं। यह किसी एक ग्राहक को किसी भी समय एक से अधिक बार पारस्परिक रूप से उधार लेने की संभावना को समाप्त करता है, इसलिए उधार चेकर को खुश किया जाता है।

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());
}
4
Pantonshire 29 जिंदा 2021, 20:53