Iteratory strumieniowania

Podczas rozmowy GoogleAdsService.search_stream zwracany jest iterator odpowiedzi na bieżąco. Ten iterator powinien pozostać w ten sam zakres co klient GoogleAdsService, aby uniknąć uszkodzone strumienie lub błędy segmentacji. Dzieje się tak, ponieważ obiekt gRPC Channel jest do czyszczenia pamięci, gdy otwarty obiekt GoogleAdsService wykracza poza zakres. Jeśli obiekt GoogleAdsService nie jest już w zakresie do momentu iteracji ma miejsce w wyniku funkcji search_stream, obiekt Channel może już powoduje zniszczenie, powodując niezdefiniowane zachowanie, gdy iterator próbuje pobrać następną wartość.

Ten kod pokazuje nieprawidłowe użycie iteratorów strumieniowania:

def stream_response(client, customer_id, query):
    return client.get_service("GoogleAdsService", version="v22").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 został utworzony w innym zakresu, z którego uzyskano dostęp do iteratora. W rezultacie obiekt Channel może zostanie zniszczona, zanim iterator przetworzy całą odpowiedź.

Zamiast tego iterator strumieniowania powinien pozostawać w tym samym zakresie co Klient GoogleAdsService, dopóki jest używany:

def main(client, customer_id):
    ga_service = client.get_service("GoogleAdsService", version="v22")
    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.