投票报告状态

展示广告和Video 360 报告无法即时生成。展示广告和Video 360 可能会 创建报告文件需要几分钟到一小时多时间

要确定查询是否已运行完毕,请定期使用 queries.reports.get,然后检查资源的 metadata.status.state 字段已更新为 DONEFAILED。此过程称为“轮询”。

对长时间运行的报告进行低效的轮询实现检查会消耗 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>');
}