投票报告状态
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
展示广告和Video 360 报告无法即时生成。展示广告和Video 360 可能会
创建报告文件需要几分钟到一小时多时间
如需确定查询是否已运行完毕,请定期使用 queries.reports.get
检索报告,然后检查资源的 metadata.status.state
字段是否已更新为 DONE
或 FAILED
。此过程称为“轮询”。
对长时间运行的报告进行检查的低效轮询实现会消耗大量的 API 请求配额。为了限制重试次数并节省配额
请使用指数退避算法。
下面展示了如何使用指数退避算法轮询报告:
Java
//This example the following import.
import com.google.api.client.util.ExponentialBackOff;
// The ID of the parent query.
Long queryId = query-id;
// The ID of the running report.
Long reportId = report-id;
// Minimum amount of time between polling requests. Defaults to 5 seconds.
final int MIN_RETRY_INTERVAL_IN_MILLIS = 5_000;
// Maximum amount of time between polling requests. Defaults to 5 minutes.
final int MAX_RETRY_INTERVAL_IN_MILLIS = 5 * 60_000;
// Maximum amount of time to spend polling. Defaults to 5 hours.
final int MAX_RETRY_ELAPSED_TIME_IN_MILLIS = 5 * 60 * 60_000;
// Configure reports.get request.
Reports.Get reportGetRequest =
service.queries().reports().get(queryId, reportId);
// Get initial report object.
Report report = reportGetRequest.execute();
// Configure exponential backoff for checking the status of our report.
ExponentialBackOff backOff =
new ExponentialBackOff.Builder()
.setInitialIntervalMillis(MIN_RETRY_INTERVAL_IN_MILLIS)
.setMaxIntervalMillis(MAX_RETRY_INTERVAL_IN_MILLIS)
.setMaxElapsedTimeMillis(MAX_RETRY_ELAPSED_TIME_IN_MILLIS)
.build();
// Poll report while it is running.
while (!report.getMetadata().getStatus().getState().equals("DONE")
&& !report.getMetadata().getStatus().getState().equals("FAILED")) {
long backoffMillis = backOff.nextBackOffMillis();
if (backoffMillis == ExponentialBackOff.STOP) {
break;
}
System.out.printf(
"Report %s still running, sleeping for %s seconds.%n",
reportId,
backoffMillis / 1000);
Thread.sleep(backoffMillis);
// Get current status of operation.
report = reportGetRequest.execute();
}
// Print the result of the report generation.
if (report.getMetadata().getStatus().getState().equals("DONE")) {
System.out.printf(
"Report %s was successfully generated.%n",
report.getKey().getReportId());
} else if (report.getMetadata().getStatus().getState().equals("FAILED")) {
System.out.printf(
"Report %s finished in error.%n",
report.getKey().getReportId());
} else {
System.out.println("Report generation deadline exceeded.");
}
Python
# The ID of the parent query.
query_id = query-id
# The ID of the report.
report_id = report-id
# The following values control retry behavior while
# the report is processing.
# Minimum amount of time between polling requests. Defaults to 5 seconds.
min_retry_interval = 5
# Maximum amount of time between polling requests. Defaults to 5 minutes.
max_retry_interval = 5 * 60
# Maximum amount of time to spend polling. Defaults to 5 hours.
max_retry_elapsed_time = 5 * 60 * 60
# Configure the queries.reports.get request.
get_request = service.queries().reports().get(
queryId=query_id,reportId=report_id)
sleep = 0
# Poll report while it is running.
start_time = time.time()
while True:
# Get current status of the report
report = get_request.execute()
# Print status if report is finished or deadline is exceeded.
if report["metadata"]["status"]["state"] == "DONE":
print(f'Report {report["key"]["reportId"]} was successfully generated.')
break
elif report["metadata"]["status"]["state"] == "FAILED":
print(f'Report {report["key"]["reportId"]} finished in error.')
break
elif time.time() - start_time > max_retry_elapsed_time:
print("Report generation deadline exceeded.")
break
sleep = next_sleep_interval(sleep)
print(
f'Report {report["key"]["reportId"]} still running, sleeping for '
f'{sleep} seconds.')
time.sleep(sleep)
def next_sleep_interval(previous_sleep_interval):
"""Calculates the next sleep interval based on the previous."""
min_interval = previous_sleep_interval or min_retry_interval
max_interval = previous_sleep_interval * 3 or min_retry_interval
return min(
max_retry_interval, random.randint(min_interval, max_interval))
PHP
// The ID of the parent query.
$queryId = query-id;
// The ID of the running report.
$reportId = report-id;
// Minimum amount of time between polling requests. Defaults to 5 seconds.
$minRetryInterval = 5;
// Maximum amount of time between polling requests. Defaults to 5 minutes.
$maxRetryInterval = 300;
// Maximum amount of time to spend polling. Defaults to 5 hours.
$maxRetryElapsedTime = 18000;
$sleepInterval = 0;
$startTime = time();
// Get initial report object.
$report = $this->service->queries_reports->get($queryId, $reportId);
// Regularly poll report status using exponential backoff.
while (
$report->getMetadata()->getStatus()->getState() !== "DONE"
&& $report->getMetadata()->getStatus()->getState() !== "FAILED"
) {
// If the operation has exceeded the set deadline, throw an exception.
if (time() - $startTime > $maxRetryElapsedTime) {
printf('SDF download task processing deadline exceeded\n');
break;
}
// Generate the next sleep interval using exponential backoff logic.
$sleepInterval = min(
$maxRetryInterval,
rand(
max($minRetryInterval, $sleepInterval),
max($minRetryInterval, $sleepInterval * 3)
)
);
// Sleep before retrieving the report again.
printf(
'Report is %d still running, sleeping for %d seconds<br>',
$reportId,
$sleepInterval
);
sleep($sleepInterval);
// Retrieve the report.
$report = $this->service->queries_reports->get($queryId, $reportId);
}
// Print the result of the report generation.
if($report->getMetadata()->getStatus()->getState() == "DONE") {
printf('Report %d was successfully generated.<br>', $reportId);
} else if($report->getMetadata()->getStatus()->getState() == "FAILED") {
printf('Report %d finished in error.<br>', $reportId);
} else {
print('Report generation deadline exceeded.<br>');
}
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-31。
[null,null,["最后更新时间 (UTC):2025-08-31。"],[[["\u003cp\u003eDisplay & Video 360 reports are not generated instantly and can take several minutes to over an hour to complete.\u003c/p\u003e\n"],["\u003cp\u003eYou need to periodically check the report status using the \u003ccode\u003equeries.reports.get\u003c/code\u003e method and the \u003ccode\u003emetadata.status.state\u003c/code\u003e field to see if it's 'DONE' or 'FAILED'.\u003c/p\u003e\n"],["\u003cp\u003eTo avoid excessive API requests and conserve quota, implement exponential backoff when polling for report status.\u003c/p\u003e\n"],["\u003cp\u003eThe provided code samples (Java, Python, PHP) demonstrate how to poll report status with exponential backoff.\u003c/p\u003e\n"]]],[],null,["# Poll report status\n\nDisplay \\& Video 360 reports don't generate instantaneously. Display \\& Video 360 might\ntake multiple minutes to over an hour to create a report file.\n\nTo determine if your query finished running, regularly retrieve the report using\n[`queries.reports.get`](/bid-manager/reference/rest/current/queries.reports/get), then check if the resource's\n[`metadata.status.state`](/bid-manager/reference/rest/current/queries.reports#ReportStatus.FIELDS.state) field has been updated to `DONE` or\n`FAILED`. This process is known as \"polling\".\n\nAn inefficient polling implementation checking on a long-running report consumes\na lot of [API request quota](/bid-manager/quotas). To limit retries and conserve quota,\nuse [exponential backoff](/bid-manager/guides/general/best-practices#exponential_backoff).\n\nHere's how to poll a report using exponential backoff: \n\n### Java\n\n```java\n//This example the following import.\nimport com.google.api.client.util.ExponentialBackOff;\n\n// The ID of the parent query.\nLong queryId = query-id;\n\n// The ID of the running report.\nLong reportId = report-id;\n\n// Minimum amount of time between polling requests. Defaults to 5 seconds.\nfinal int MIN_RETRY_INTERVAL_IN_MILLIS = 5_000;\n\n// Maximum amount of time between polling requests. Defaults to 5 minutes.\nfinal int MAX_RETRY_INTERVAL_IN_MILLIS = 5 * 60_000;\n\n// Maximum amount of time to spend polling. Defaults to 5 hours.\nfinal int MAX_RETRY_ELAPSED_TIME_IN_MILLIS = 5 * 60 * 60_000;\n\n// Configure reports.get request.\nReports.Get reportGetRequest =\n service.queries().reports().get(queryId, reportId);\n\n// Get initial report object.\nReport report = reportGetRequest.execute();\n\n// Configure exponential backoff for checking the status of our report.\nExponentialBackOff backOff =\n new ExponentialBackOff.Builder()\n .setInitialIntervalMillis(MIN_RETRY_INTERVAL_IN_MILLIS)\n .setMaxIntervalMillis(MAX_RETRY_INTERVAL_IN_MILLIS)\n .setMaxElapsedTimeMillis(MAX_RETRY_ELAPSED_TIME_IN_MILLIS)\n .build();\n\n// Poll report while it is running.\nwhile (!report.getMetadata().getStatus().getState().equals(\"DONE\")\n && !report.getMetadata().getStatus().getState().equals(\"FAILED\")) {\n long backoffMillis = backOff.nextBackOffMillis();\n if (backoffMillis == ExponentialBackOff.STOP) {\n break;\n }\n System.out.printf(\n \"Report %s still running, sleeping for %s seconds.%n\",\n reportId,\n backoffMillis / 1000);\n Thread.sleep(backoffMillis);\n\n // Get current status of operation.\n report = reportGetRequest.execute();\n}\n\n// Print the result of the report generation.\nif (report.getMetadata().getStatus().getState().equals(\"DONE\")) {\n System.out.printf(\n \"Report %s was successfully generated.%n\",\n report.getKey().getReportId());\n} else if (report.getMetadata().getStatus().getState().equals(\"FAILED\")) {\n System.out.printf(\n \"Report %s finished in error.%n\",\n report.getKey().getReportId());\n} else {\n System.out.println(\"Report generation deadline exceeded.\");\n}\n```\n\n### Python\n\n```python\n# The ID of the parent query.\nquery_id = query-id\n\n# The ID of the report.\nreport_id = report-id\n\n# The following values control retry behavior while\n# the report is processing.\n# Minimum amount of time between polling requests. Defaults to 5 seconds.\nmin_retry_interval = 5\n# Maximum amount of time between polling requests. Defaults to 5 minutes.\nmax_retry_interval = 5 * 60\n# Maximum amount of time to spend polling. Defaults to 5 hours.\nmax_retry_elapsed_time = 5 * 60 * 60\n\n# Configure the queries.reports.get request.\nget_request = service.queries().reports().get(\n queryId=query_id,reportId=report_id)\n\nsleep = 0\n\n# Poll report while it is running.\nstart_time = time.time()\nwhile True:\n # Get current status of the report\n report = get_request.execute()\n\n # Print status if report is finished or deadline is exceeded.\n if report[\"metadata\"][\"status\"][\"state\"] == \"DONE\":\n print(f'Report {report[\"key\"][\"reportId\"]} was successfully generated.')\n break\n elif report[\"metadata\"][\"status\"][\"state\"] == \"FAILED\":\n print(f'Report {report[\"key\"][\"reportId\"]} finished in error.')\n break\n elif time.time() - start_time \u003e max_retry_elapsed_time:\n print(\"Report generation deadline exceeded.\")\n break\n\n sleep = next_sleep_interval(sleep)\n print(\n f'Report {report[\"key\"][\"reportId\"]} still running, sleeping for '\n f'{sleep} seconds.')\n time.sleep(sleep)\n\ndef next_sleep_interval(previous_sleep_interval):\n \"\"\"Calculates the next sleep interval based on the previous.\"\"\"\n min_interval = previous_sleep_interval or min_retry_interval\n max_interval = previous_sleep_interval * 3 or min_retry_interval\n return min(\n max_retry_interval, random.randint(min_interval, max_interval))\n```\n\n### PHP\n\n```php\n// The ID of the parent query.\n$queryId = \u003cvar translate=\"no\"\u003equery-id\u003c/var\u003e;\n\n// The ID of the running report.\n$reportId = \u003cvar translate=\"no\"\u003ereport-id\u003c/var\u003e;\n\n// Minimum amount of time between polling requests. Defaults to 5 seconds.\n$minRetryInterval = 5;\n// Maximum amount of time between polling requests. Defaults to 5 minutes.\n$maxRetryInterval = 300;\n// Maximum amount of time to spend polling. Defaults to 5 hours.\n$maxRetryElapsedTime = 18000;\n\n$sleepInterval = 0;\n$startTime = time();\n\n// Get initial report object.\n$report = $this-\u003eservice-\u003equeries_reports-\u003eget($queryId, $reportId);\n\n// Regularly poll report status using exponential backoff.\nwhile (\n $report-\u003egetMetadata()-\u003egetStatus()-\u003egetState() !== \"DONE\"\n && $report-\u003egetMetadata()-\u003egetStatus()-\u003egetState() !== \"FAILED\"\n) {\n\n // If the operation has exceeded the set deadline, throw an exception.\n if (time() - $startTime \u003e $maxRetryElapsedTime) {\n printf('SDF download task processing deadline exceeded\\n');\n break;\n }\n\n // Generate the next sleep interval using exponential backoff logic.\n $sleepInterval = min(\n $maxRetryInterval,\n rand(\n max($minRetryInterval, $sleepInterval),\n max($minRetryInterval, $sleepInterval * 3)\n )\n );\n\n // Sleep before retrieving the report again.\n printf(\n 'Report is %d still running, sleeping for %d seconds\u003cbr\u003e',\n $reportId,\n $sleepInterval\n );\n sleep($sleepInterval);\n\n // Retrieve the report.\n $report = $this-\u003eservice-\u003equeries_reports-\u003eget($queryId, $reportId);\n}\n\n// Print the result of the report generation.\nif($report-\u003egetMetadata()-\u003egetStatus()-\u003egetState() == \"DONE\") {\n printf('Report %d was successfully generated.\u003cbr\u003e', $reportId);\n} else if($report-\u003egetMetadata()-\u003egetStatus()-\u003egetState() == \"FAILED\") {\n printf('Report %d finished in error.\u003cbr\u003e', $reportId);\n} else {\n print('Report generation deadline exceeded.\u003cbr\u003e');\n}\n```"]]