问题描述
我有一个更大的Flask RESTful API的组件,其目的是将一个非常大的文件(几个GB,特别是一个OVA虚拟化映像文件)作为POST主体,然后将其直接保存到一个块设备中(在我的代码中被视为普通文件。
我遇到的问题有两个:
(1)在上传期间,在进行save()
调用之前,Flask正在将文件写出到临时文件中。这是阻塞的,并且在此保存过程中(连接速度较慢的大文件最多要花费几分钟),整个API都会被阻塞;对API的其他请求必须等待上传完成。
(2)我尝试通过推迟初始保存并使用自定义stream_factory
到parse_form_data
(直接写到目标位置)而不是使用标准Flask RESTful解析,然后尝试解决此问题。呼叫save()
。这样可以避免写入临时文件(在我的情况下是两次写入并占用大量临时空间),但是阻塞行为是相同的,只是稍后在我的代码路径中发生。
我尝试过的事情:
- 我已经尝试了标准
save()
和自定义parse_form_data
,如上所述。没有效果。 - 我已经尝试了默认的烧瓶
run()
和threaded=True
以及不使用threaded=True
的情况。没有效果。 - 除了默认的Flask
run()
外,我还尝试了两种PyWsgi。没有效果。 - 使用PyWSHI,我已经尝试过
monkey.patch_all()
,而没有尝试过。没有效果。 - 我尝试使用
os.set_blocking
通过自定义stream_factory
方法禁用阻止。没有效果。 - 我尝试在线程中运行
parse_form_data
,但是由于我必须join()
来避免其余的代码继续进行,直到完成上传,所以这也没有效果。 li>
相关的代码可以在我实施自定义stream_factory
解决方案的this particular commit to my project中找到;请注意,我这样做是为了阻止重复保存,而不是解决此问题,但是它显示了我正在使用的代码路径。
这种让我感到难过的东西;我都需要支持这些大文件上传,但是在上传发生时,我无法让API阻止其他请求。有什么方法可以阻止这些大文件上传阻止其他对API的请求?
编辑:我发现解决方案是仅对我的API使用Flask“调试”服务器。它在threading=True
上可以正常工作,而无需打补丁业务,而Gevent / PyWsgi则不能,并且在我的用例中,“调试”服务器的功能已足够。认为这是封闭的,没有提出解释或“适当的”解决方案。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)