[最近,我已将express.js中的REST服务器代码移至使用FastAPI。到目前为止,直到最近,我在过渡方面都取得了成功。我注意到基于firebase的python admin sdk文档,与node.js不同,python sdk处于阻塞状态。文档说here:
在Python和Go Admin SDK中,所有写入方法均处于阻塞状态。也就是说,在将写入提交到数据库之前,write方法不会返回。
我认为此功能对我的代码有一定影响。这也可能是我构造代码的方式。我的一个文件中的一些代码如下:
from app.services.new_service import nService
from firebase_admin import db
import json
import redis
class TryNewService:
async def tryNew_func(self, request):
# I've already initialized everything in another file for firebase
ref = db.reference()
r = redis.Redis()
holdingData = await nService().dialogflow_session(request)
fulfillmentText = json.dumps(holdingData[-1])
body = await request.json()
if ("user_prelimInfo_address" in holdingData):
holdingData.append("session")
holdingData.append(body["session"])
print(holdingData)
return(holdingData)
else:
if (("Default Welcome Intent" in holdingData)):
pass
else:
UserVal = r.hget(name='{}'.format(body["session"]), key="userId").decode("utf-8")
ref.child("users/{}".format(UserVal)).child("c_data").set({holdingData[0]:holdingData[1]})
print(holdingData)
return(fulfillmentText)
我的代码中是否存在使用ref.set()
行的阻塞效果的解决方法? Kinda喜欢在node.js中添加回调?我是python 3异步世界的新手。
截至2020年6月13日的更新:因此,我添加了以下代码,现在获得
RuntimeError: Task attached to a different loop
。在第二条else语句中,我执行以下操作:
loop = asyncio.new_event_loop()
UserVal = r.hget(name='{}'.format(body["session"]), key="userId").decode("utf-8")
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as pool:
result = await loop.run_in_executor(pool, ref.child("users/{}".format(UserVal)).child("c_data").set({holdingData[0]:holdingData[1]}))
print("custom thread pool:{}".format(result))
有了这个新的RuntimeError,我希望能对您有所帮助。
使用ThreadPoolExecutor
在事件循环上运行阻止数据库调用。参见https://medium.com/@hiranya911/firebase-python-admin-sdk-with-asyncio-d65f39463916