如何将阻塞函数设置为在执行程序中运行,这样结果就不重要了,这样主线程就不会等待或被它减慢。
老实说,我不确定这是否是正确的解决方案,我想要的是从主进程中分离出某种类型的处理队列,这样它就不会阻止服务器应用程序返回请求,因为这种类型的web服务器对许多请求运行一个工作进程。
我最好远离像芹菜这样的解决方案,但如果这是最好的,我愿意学习它。
这里的上下文是一个异步web服务器,它生成带有大图像的pdf文件。
app = Sanic()
#App "global" worker
executor = ProcessPoolExecutor(max_workers=5)
app.route('/')
async def getPdf(request):
asyncio.create_task(renderPdfsInExecutor(request.json))
#This should be returned "instantly" regardless of pdf generation time
return response.text('Pdf being generated, it will be sent to your email when done')
async def renderPdfsInExecutor(json):
asyncio.get_running_loop.run_in_executor(executor, syncRenderPdfs, json)
def syncRenderPdfs(json)
#Some PDF Library that downloads images synchronously
pdfs = somePdfLibrary.generatePdfsFromJson(json)
sendToDefaultMail(pdfs)
上面的代码给出了错误(是的,它是以管理员身份运行的):
PermissionError [WinError 5] Access denied
Future exception was never retrieved
奖励问题:通过在executor中运行异步循环,我能获得什么吗?因此,如果它同时处理多个PDF请求,它将在它们之间分配处理。如果是,我该怎么做?
发布于 2019-02-21 22:21:35
您可以查看asyncio.gather(*tasks)来并行运行多个任务。
请记住,并行任务只有在有io限制而不是阻塞的情况下才能正常工作。
python文档(https://docs.python.org/3/library/asyncio-task.html)中的一个示例:
import asyncio
async def factorial(name, number):
f = 1
for i in range(2, number + 1):
print(f"Task {name}: Compute factorial({number}), currently i={i}...")
await asyncio.sleep(1)
f *= i
print(f"Task {name}: factorial({number}) = {f}")
return f
async def main():
# Schedule three calls *concurrently*:
L = await asyncio.gather(
factorial("A", 2),
factorial("B", 3),
factorial("C", 4),
)
print(L)
asyncio.run(main())
https://stackoverflow.com/questions/54749229
复制相似问题