【发布时间】:2019-07-09 15:37:21
【问题描述】:
我正在尝试使用asyncio 对 Web 服务(由 GET 查询字符串格式化)运行许多并行调用,并且所有调用都立即返回值 0。Web 服务是一个物理模拟,它返回一个整数值它的表现如何。但是,我希望该服务运行大约 2 分钟,然后返回该值,但是打印出 asyncio 中的值会立即显示 0 值。
此代码是遗传算法(运行 DEAP)的一部分,所以我想做的是有一个运行的外部(世代)循环,每个个体(构造的 URL)并行运行并执行评估。我不确定这是否有任何影响,但它是谷歌云功能。最大执行时间设置在预期评估时间范围内,最大内存也是有效的。
这是我的asyncio 函数,如果响应返回 OK,我希望看到一些有效的整数值,如果生成错误,则返回 -999:
# AsyncIO functions for interacting with Google Cloud Functions
async def fetchCF(indv: str, session: ClientSession, **kwargs) -> str:
resp = await session.request(method="GET", url=indv, **kwargs)
resp.raise_for_status()
html = await resp.text()
return html
# Dispatch the CFs and return fitness
async def callCF(indv: str, session: ClientSession, **kwargs) -> int:#float:
try:
html = await fetchCF(indv=indv, session=session, **kwargs)
except (
aiohttp.ClientError,
aiohttp.http_exceptions.HttpProcessingError,
) as e:
print(indv,e)
return -9999,
else:
return int(html),
# Called via GA
async def evalAsync(pop: set, **kwargs) -> None:
async with ClientSession(read_timeout=None) as session:
tasks = []
for p in pop:
#print(p)
indv_url = '%s?seed=%d&x0=%d&y0=%d&x1=%d&y1=%d&x2=%d&y2=%d&x3=%d&y3=%d&emitX=%d&emitY=%d' % \
(url,args.seed,int(p[0]),int(p[1]),int(p[2]),int(p[3]),int(p[4]),int(p[5]),int(p[6]),int(p[7]),int(p[8]),int(p[9]))
tasks.append(
callCF(indv=indv_url,session=session,**kwargs)
)
return await asyncio.gather(*tasks)
这是我在世代循环中如何称呼它们的方式:
for g in generations:
...
fitnesses = asyncio.run(evalAsync(population))
作为参考,该代码适用于本地物理模拟,在该模拟中,我将对 asyncio.run 的调用替换为对本地物理驱动程序的 pool.map 调用。
【问题讨论】:
-
我不是
asyncio方面的专家,但有几件事让我印象深刻。首先,您确定您的session.request()和resp.text()呼叫是awaitable?可能需要asyncio.create_task()或这里的东西。其次,我怀疑您的某些async标签是不必要的。例如,您的with ClientSession ...循环中是否需要一个?我不确定。 -
@Engineero:我在这里按照示例进行操作,因为我对
asyncio还不是很满意:Tutorial -
@Engineero:代码中没有
async错误,没有。 -
您的代码正确无误,前提是最后
return await asyncio.gather(*tasks)行缩进到async with .. as session:上下文管理器块内。您如何确定回复的速度? -
我已经删除了赏金并根据 OP 对斯蒂芬回答的评论关闭了它:我刚刚发现了一些非常奇怪的行为。我在本地运行我的代码以找出一组理想的值。然后我在我的云函数上运行这些值。第一次运行时,我得到了正确的值。然后,我在私人浏览窗口中运行了完全相同的查询字符串,即时结果为 0。然后,我刷新了前一页(它运行正确的地方),该值现在也为 0。对我来说,发生了一些可疑的事情云函数结束..
标签: python-3.x google-cloud-functions python-asyncio