生成结构化数据文件 (SDF) 可能需要几秒钟到数小时不等。当 Operation 中的 done 字段为 True 时,表示任务已完成。
Operation 由格式为 /sdfdownloadtasks/operations/{id} 的名称标识。定期使用 sdfdownloadtasks.operations.get 检索具有此名称的 Operation,以查看任务是否已完成。此过程称为“轮询”。
如果 done 为 True,则会设置 response 或 error 字段。失败的任务会设置 error 字段。分配的 Status 对象会提供有关失败的详细信息。成功完成的任务会设置 response 字段。从 response.resourceName 下载生成的结构化数据文件。
低效的轮询会消耗大量 API 请求配额。使用指数退避算法限制重试次数并节省配额。
以下是如何使用指数退避算法轮询 SDF 下载任务:
Java
// Provide the name of the sdfdownloadtask operation. String operationName = operation-name; // Configure the Operations.get request. Sdfdownloadtasks.Operations.Get operationRequest = service.sdfdownloadtasks().operations().get(operationName); // Configure exponential backoff for checking the status of our operation. ExponentialBackOff backOff = new ExponentialBackOff.Builder() .setInitialIntervalMillis(5000) // setting initial interval to five seconds .setMaxIntervalMillis(5000 * 60) // setting max interval to five minutes .setMaxElapsedTimeMillis(5000 * 60 * 60) // setting max elapsed time to five hours .build(); long backoffMillis = 0; // Create default operation variable. Operation operation = new Operation(); do { // Sleep before retrieving operation again. Thread.sleep(backoffMillis); // Retrieve operation. operation = operationRequest.execute(); // If operation is not done, calculate next sleep period. if (operation.getDone() == null) { backoffMillis = backOff.nextBackOffMillis(); if (backoffMillis == ExponentialBackOff.STOP) { System.out.printf("The operation has taken more than five hours to complete.%n"); break; } System.out.printf( "Operation %s is still running, sleeping for %s milliseconds.%n", operationName, backoffMillis); } } while (operation.getDone() == null); // Check whether operation finished with an error, or is completed and ready to download. if (operation.getDone() != null) { if (operation.getError() != null) { System.out.printf( "The operation finished in error with code %s: %s%n", operation.getError().getCode(), operation.getError().getMessage()); } else { System.out.printf( "The operation completed successfully. Resource %s was created.%n", operation.getResponse().get("resourceName").toString()); } }
Python
# Provide the name of the sdfdownloadtask operation. operation_name = operation-name # Set the following values that control retry behavior while the operation # is running. # 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 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)) # Configure the sdfdownloadtasks.operations.get request. get_request = service.sdfdownloadtasks().operations().get(name=operation_name) sleep = 0 start_time = time.time() while True: # Retrieve the operation. operation = get_request.execute() if "done" in operation: if "error" in operation: print( f"The operation finished in error with code " f'{operation["error"]["code"]}: {operation["error"]["message"]}' ) else: print( f"The operation completed successfully. The resulting files can be " f'downloaded at {operation["response"]["resourceName"]}.' ) break elif time.time() - start_time > max_retry_elapsed_time: print("SDF generation deadline exceeded.") break sleep = next_sleep_interval(sleep) print( f"Operation {operation_name} is still running, sleeping for " f"{sleep} seconds." ) time.sleep(sleep)
PHP
// The following values control retry behavior while the task is processing. // 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; // Provide the name of the sdfdownloadtask operation. $operationName = operation-name; // Poll operation. $sleep = 0; $startTime = time(); do { try { // Call the API, retrieving the SDF Download Task. $operation = $this->service->sdfdownloadtasks_operations->get( $operationName ); } catch (\Exception $e) { $this->renderError($e); return; } // Check if retrieved operation is finished. if ($operation->getDone() === true) { if($operation->getError() !== null) { $error = $operation->getError(); printf( 'The operation finished in error with code %s: %s<br>', $error->setCode(), $error->setMessage() ); break; } else { $response = $operation->getResponse(); printf( 'The operation completed successfully. Resource %s ' . 'was created.<br>', $response['resourceName'] ); break; } } elseif (time() - $startTime > self::MAX_RETRY_ELAPSED_TIME) { print '<p>SDF download task processing deadline exceeded</p>'; break; } // Generate next sleep interval. $minInterval = max($minRetryInterval, $sleep); $maxInterval = max( $minRetryInterval, $sleep * 3 ); $sleep = min($maxRetryInterval, rand($minInterval, $maxInterval)); // Sleep a determined amount of time before retrieving the operation // again. printf( 'Operation %s is still running, sleeping for %d seconds<br>', $operationName, $sleep ); sleep($sleep); } while (true);