我在执行异步GAE NDB数据存储区查询时遇到问题。出于测试目的,假设我执行
l = []
for i in range (0,50):
qry = NDBNetLoc.query(NDBNetLoc.netloc == 'imdb.com').get()
l.append(qry)
其中netloc是我的模型的索引属性(没有其他属性;我在这里修复字符串,但一般来说查询的字符串将是唯一的)。这当然会在请求中形成“瀑布”:
http://imgur.com/a/uckrh#FAON8pZ
这是规范类型的请求,应该是异步的(根据谷歌)。相反,我执行
futs = []
for i in range (0,50):
qry = NDBNetLoc.query(NDBNetLoc.netloc == 'imdb.com').get_async()
futs.append(qry)
for fut in futs:
l.append(fut.get_result())
但我没有看到改善。虽然每个请求一个接一个地触发,但每个呼叫需要更长的时间(持续时间随着i
的增加而减少)
http://imgur.com/a/uckrh#eUVfLrG
此外,似乎请求在第二个for循环之前不会触发。如果我在此循环前添加time.sleep(2)
,我会得到类似
http://imgur.com/a/uckrh#SztJnkn
这对我来说非常困惑,因为我认为在创建Future对象后会立即触发请求。所以我的两个问题是:1)为什么在每个未来对象被实例化的时刻都没有触发请求; 2)为什么每个请求现在需要更长的时间(以异步或同步方式执行此操作的时间是相同的时间条件完成)?
编辑:
我应该补充一点,我没有对一个唯一的netloc
列表做一个简单的IN查询的原因是因为我最终运行了更复杂的查询(即得到所有具有propertyA = foo的Model2和一个祖先是从第一个查询返回的特定NDBNetLoc,对于许多NDBNetLocs和许多foo都是。
答案 0 :(得分:-2)
我在SO上找到了这个问题的摘要...我不熟悉Global Interpreter Lock及其在这里的应用,但我想解码我的RPC的代码是CPython字节码,并且解释器不是线程安全的,因此每次调用都会锁定它。猜猜我会转移到Java .....