Durante la chiamata a GoogleAdsService.search_stream
, viene restituito un iteratore di risposta in modalità flusso. Questo iteratore deve rimanere nello stesso ambito del client GoogleAdsService
mentre viene utilizzato per evitare stream interrotti o errori di segmentazione. Questo perché l'oggetto gRPC Channel
viene eliminato in modo garbage quando l'oggetto GoogleAdsService
aperto esce dall'ambito.
Se l'oggetto GoogleAdsService
non rientra più nell'ambito quando viene eseguita l'iterazione sul risultato di search_stream
, l'oggetto Channel
potrebbe essere già stato eliminato, causando un comportamento indefinito quando l'iteratore tenta di recuperare il valore successivo.
Il seguente codice dimostra l'uso erroneo degli iteratori di streaming:
def stream_response(client, customer_id, query):
return client.get_service("GoogleAdsService", version="v16").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.
Nel codice riportato sopra, l'oggetto GoogleAdsService
viene creato in un ambito diverso da quello in cui si accede all'iteratore. Di conseguenza, l'oggetto Channel
potrebbe
essere eliminato prima che l'iteratore consumi l'intera risposta.
L'iteratore di flussi di dati deve invece rimanere nello stesso ambito del client GoogleAdsService
finché viene utilizzato:
def main(client, customer_id):
ga_service = client.get_service("GoogleAdsService", version="v16")
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.