gpt4 book ai didi

Python run_in_executor 忘记了?

转载 作者:太空狗 更新时间:2023-10-30 02:51:47 25 4
gpt4 key购买 nike

我如何设置一个阻塞函数在执行器中运行,以一种结果无关紧要的方式,这样主线程不应该等待或被它减慢。

老实说,我不确定这是否是正确的解决方案,我想要的只是将某种类型的处理队列与主进程分开,这样它就不会阻止服务器应用程序返回请求,因为这种类型的网络服务器运行一个工作人员来处理许多请求。

我最好远离像 Celery 这样的解决方案,但如果那是最佳方案,我愿意学习它。

这里的上下文是一个异步网络服务器,它生成带有大图像的 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

奖励问题:通过在执行程序中运行异步循环,我能得到什么吗?因此,如果它同时处理多个 PDF 请求,它将在它们之间分配处理。如果是,我该怎么做?

最佳答案

好吧,那么首先有一个误会。这个

async def getPdf(request):
asyncio.create_task(renderPdfsInExecutor(request.json))
...

async def renderPdfsInExecutor(json):
asyncio.get_running_loop.run_in_executor(executor, syncRenderPdfs, json)

是多余的。做就够了

async def getPdf(request):
asyncio.get_running_loop.run_in_executor(executor, syncRenderPdfs, request.json)
...

或者(因为你不想等待)甚至更好

async def getPdf(request):
executor.submit(syncRenderPdfs, request.json)
...

现在您遇到的问题是因为 syncRenderPdfs 抛出 PermissionError。它没有被处理,所以 Python 警告你“嘿,一些后台代码抛出了一个错误。但是代码不属于任何人所以到底是什么?”。这就是为什么您得到 Future exception was never retrieved 的原因。 您的 pdf 库本身有问题,而不是 asyncio。一旦你解决了这个内部问题,安全也是一个好主意:

def syncRenderPdfs(json)
try:
#Some PDF Library that downloads images synchronously
pdfs = somePdfLibrary.generatePdfsFromJson(json)
sendToDefaultMail(pdfs)
except Exception:
logger.exception('Something went wrong') # or whatever

您的“权限被拒绝”问题完全不同,您应该对其进行调试和/或为此发布一个单独的问题。

至于最后一个问题:是的,executor会在worker之间排队并平均分配任务。

编辑:正如我们在评论中所说的那样,实际问题可能与您工作的 Windows 环境有关。或者更准确地说,使用 ProcessPoolExecutor,即生成进程可能会更改权限。我建议使用 ThreadPoolExecutor,假设它在平台上运行良好。

关于Python run_in_executor 忘记了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54749229/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com