स्ट्रीमिंग इटरेटर

GoogleAdsService.search_stream को कॉल करने पर, स्ट्रीमिंग रिस्पॉन्स के लिए एक आइटरेटर दिखता है. इसका इस्तेमाल करते समय, यह इटरेटर GoogleAdsService क्लाइंट के उसी दायरे में रहना चाहिए, ताकि बिगड़ी हुई स्ट्रीम या सेगमेंटेशन से जुड़ी गड़बड़ियों से बचा जा सके. ऐसा इसलिए होता है, क्योंकि open GoogleAdsService ऑब्जेक्ट के दायरे से बाहर निकलने के बाद, gRPC Channel ऑब्जेक्ट को ग़ैर-ज़रूरी डेटा के तौर पर हटा दिया जाता है. अगर search_stream के नतीजे पर, GoogleAdsService ऑब्जेक्ट के दोहराए जाने तक वह स्कोप में नहीं है, तो हो सकता है कि Channel ऑब्जेक्ट पहले ही नष्ट हो गया हो. इससे, जब iterator अगली वैल्यू को वापस पाने की कोशिश करता है, तो अनिश्चित व्यवहार होता है.

यहां दिए गए कोड में, स्ट्रीमिंग आइटरेटर्स के गलत इस्तेमाल का उदाहरण दिया गया है:

def stream_response(client, customer_id, query):
    return client.get_service("GoogleAdsService", version="v18").search_stream(customer_id, query=query)

def main(client, customer_id):
    query = "SELECT campaign.name FROM campaign LIMIT 10"
    response = stream_response(client, customer_id, query=query)
    # Access the iterator in a different scope from where the service object was created.
    try:
        for batch in response:
            # Iterate through response, expect undefined behavior.

ऊपर दिए गए कोड में, GoogleAdsService ऑब्जेक्ट को किसी ऐसे अलग स्कोप में बनाया गया है जहां से iterator को ऐक्सेस किया जाता है. इस वजह से, हो सकता है कि iterator पूरे रिस्पॉन्स का इस्तेमाल करने से पहले ही Channel ऑब्जेक्ट को नष्ट कर दे.

इसके बजाय, स्ट्रीमिंग आइटरेटर का इस्तेमाल होने तक, वह GoogleAdsService क्लाइंट के दायरे में ही रहना चाहिए:

def main(client, customer_id):
    ga_service = client.get_service("GoogleAdsService", version="v18")
    query = "SELECT campaign.name FROM campaign LIMIT 10"
    response = ga_service.search_stream(customer_id=customer_id, query=query)
    # Access the iterator in the same scope as where the service object was created.
    try:
        for batch in response:
            # Successfully iterate through response.