Iteratory strumieniowania

Po wywołaniu funkcji GoogleAdsService.search_streamzwracany jest iterator odpowiedzi przesyłanej na bieżąco. Ten iterator powinien pozostawać w tym samym zakresie co klient GoogleAdsService, aby uniknąć zerwania strumieni lub błędów segmentacji. Dzieje się tak, ponieważ obiekt gRPC Channel jest usuwany, gdy obiekt otwarty GoogleAdsService wychodzi poza zakres. Jeśli obiekt GoogleAdsService nie jest już dostępny w zakresie w momencie iteracji na wyniku funkcji search_stream, obiekt Channel może być już zniszczony, co spowoduje nieokreślone działanie podczas próby pobrania następnej wartości przez iterator.

Poniższy kod pokazuje nieprawidłowe użycie przewijanych iteratorów:

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.

W powyższym kodzie obiekt GoogleAdsService jest tworzony w ramach innego zakresu niż ten, w którym uzyskujesz dostęp do iteratora. W efekcie obiekt Channel może zostać usunięty, zanim iterator przetworzy całą odpowiedź.

Zamiast tego iterator strumieniowy powinien pozostawać w tym samym zakresie co klient GoogleAdsService przez cały czas jego używania:

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.