问题描述
此问题与BigQuery Python客户端中QueryJob对象的timeout
方法中的result
参数有关。
相对于版本1.24.0,看来timeout
的含义已更改。
例如,documentation for QueryJob's result
in version 1.24.0指出超时为:
使用重试之前等待基础HTTP传输的秒数。如果在后台进行了多个请求,则超时将解释为所有请求的大约总时间。
据我了解,这可以用作限制result
方法调用等待结果的总时间的一种方法。
例如,考虑以下脚本:
import logging
from google.cloud import bigquery
# Set logging level to DEBUG in order to see the HTTP requests
# being made by urllib3
logging.basicConfig(level=logging.DEBUG)
PROJECT_ID = "project_id" # replace by actual project ID
client = bigquery.Client(project=PROJECT_ID)
QUERY = ('SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013` '
'WHERE state = "TX" '
'LIMIT 100')
TIMEOUT = 30 # in seconds
query_job = client.query(QUERY) # API request - starts the query
assert query_job.state == 'RUNNING'
# Waits for the query to finish
iterator = query_job.result(timeout=TIMEOUT)
rows = list(iterator)
assert query_job.state == 'DONE'
据我了解,如果获取结果涉及的所有API调用加起来超过30秒,则对result
的调用将放弃。因此,timeout
在这里用来限制result
方法调用的总执行时间。
但是,更高版本引入了更改。例如,documentation for result
in 1.27.2指出超时为:
使用重试之前等待基础HTTP传输的秒数。如果在后台多次提出请求,则超时适用于每个单独的请求。
如果我正确理解这一点,那么上面的示例将完全改变含义,并且对result
的调用可能会花费30秒钟以上的时间。
我的疑问是:
谢谢。
解决方法
正如您在此fix中所看到的:
使传输层超时独立于查询超时, 即等待查询完成的最长时间。
查询超时由阻塞轮询使用,因此后端 轮询作业完成时不会阻塞太长时间,但是 运输可能有不同的超时要求,我们不希望 有时会引起不必要的超时错误。
- 将超时应用于每个基础请求
由于作业方法不再在所有请求之间分配超时,因此 方法可能会使客户端方法以相同的方式进行调整。
因此,基本区别在于,在以前的版本中,如果在下面的层中进行了许多请求,则它们将共享30秒的超时时间。换句话说,如果第一个请求花费20秒,第二个请求将在10秒后超时。 在新版本中,每个请求都将有30秒的时间。
关于用例,基本上取决于您的应用程序。如果您不能长时间等待可能丢失的请求,则可以减少超时。