异步计算dask数组块(dask+;FastAPI)

异步计算dask数组块(dask+;FastAPI),dask,dask-distributed,fastapi,uvicorn,Dask,Dask Distributed,Fastapi,Uvicorn,我正在构建一个FastAPI应用程序,它将为Dask数组的块提供服务。我想与你并肩作战。下面是一个mcve,它演示了我试图在应用程序的服务器端和客户端执行的操作: 服务器端: 导入时间 将dask.array导入为da 将numpy作为np导入 进口乌维康 从dask.distributed导入客户端 从fastapi导入fastapi app=FastAPI() #创建我们可以服务的dask阵列 data=da.from_数组(np.arange(0,1e6,dtype=np.int),chu

我正在构建一个FastAPI应用程序,它将为Dask数组的块提供服务。我想与你并肩作战。下面是一个mcve,它演示了我试图在应用程序的服务器端和客户端执行的操作:

服务器端:

导入时间
将dask.array导入为da
将numpy作为np导入
进口乌维康
从dask.distributed导入客户端
从fastapi导入fastapi
app=FastAPI()
#创建我们可以服务的dask阵列
data=da.from_数组(np.arange(0,1e6,dtype=np.int),chunks=100)
异步定义获取块(块id):
“”“将dask数组的一个块作为列表返回”“”
block\u data=data.blocks[block\u id].compute()
返回块_data.tolist()
@app.get(“/”)
异步def get_root():
时间。睡眠(1)
返回{“你好”:“世界”}
@app.get(“/{block_id}”)
异步def get_块(块id:int):
time.sleep(1)#因此我们可以测试并发性
我的列表=等待获取块(块id)
返回{“块”:我的列表}
如果名称=“\uuuuu main\uuuuuuuu”:
客户=客户(n_工人=2)
打印(客户端)
打印(客户端.群集.仪表板链接)
运行(应用程序,主机=“0.0.0.0”,端口=9000,日志级别=“调试”)
客户端

导入dask
导入请求
从dask.distributed导入客户端
client=client()
答复=[
dask.delayed(requests.get,pure=False)(f“http://127.0.0.1:9000/{i} )表示范围(10)内的i
]
dask.compute(响应)
在此设置中,在
\u get\u块中调用
compute()
是“阻塞”的,一次只计算一个块。我尝试了
Client(asynchronous=True)
Client.compute(dask.compute(responses)
)的各种组合,但没有任何改进。是否可以
等待
dask阵列的计算

这条线

block_data = data.blocks[block_id].compute()
这是一个阻塞呼叫。如果您改为
client.compute(data.blocks[block_id])
,您将获得一个可以与IOLoop一起使用的可期待的未来,只要Dask使用相同的循环


请注意,摄入服务器非常希望以这种方式工作(它也希望为数组和其他数据类型按块流式传输数据)。

谢谢@mdurant!关于让Dask和Uvicorn使用相同的IOLoop有什么建议吗?不,我不知道。您可以在实例化客户机时指定ioloop,但我不知道这是否足够。