该评论包含您响应网络请求和安排稍后生成 pdf 所需的一切。
asyncio.create_task(generatePdf())
但是,如果 pdf 处理速度很慢,则不是一个好主意,因为它会阻塞 asyncio 事件线程。即当前请求将很快得到响应,但后续请求必须等到 pdf 生成完成。
正确的方法是在执行器(尤其是ProcessPoolExecutor)中运行任务。
from quart import Quart
import asyncio
import time
from concurrent.futures import ProcessPoolExecutor
app = Quart(__name__)
executor = ProcessPoolExecutor(max_workers=5)
@app.route('/')
async def pdf():
t1 = time.time()
asyncio.get_running_loop().run_in_executor(executor, generatePdf)
# await generatePdf()
return 'Time to execute : {} seconds'.format(time.time() - t1)
def generatePdf():
#sync generatepdf
#send pdf link to email
app.run()
需要注意的是,由于它在不同的进程中运行,因此无法在generatePdf
没有同步的情况下访问任何数据。因此,在调用函数时传递函数所需的所有内容。
更新
如果您可以重构该generatePdf
函数并使其异步,则效果最好。
例如,如果生成 pdf 看起来像
def generatePdf():
image1 = downloadImage(image1Url)
image2 = downloadImage(image2Url)
data = queryData()
pdfFile = makePdf(image1, image2, data)
link = upLoadToS3(pdfFile)
sendEmail(link)
您可以使函数异步,如:
async def generatePdf():
image1, image2, data = await asyncio.gather(downloadImage(image1Url), downloadImage(image2Url), queryData())
pdfFile = makePdf(image1, image2, data)
link = await upLoadToS3(pdfFile)
await sendEmail(link)
注意:所有的辅助函数,如downloadImage
,queryData
都需要重写以支持async
. 这样,即使数据库或图像服务器很慢,请求也不会被阻塞。一切都在同一个异步线程中运行。
如果其中一些还不是异步的,那么它们可以与其他异步函数一起使用,run_in_executor
并且应该可以很好地与其他异步函数一起使用。