Rails - x-sendfile +临时文件
不久前,我写了一个问题关于在 Rails 应用程序中使用临时文件。在这种特殊情况下,我决定使用 tempfile
如果我还想使用 x-sendfile
指令(作为 Rails 2 中的参数,或作为配置Rails 3 中的选项),以便文件发送由我的 Web 服务器直接处理,而不是由我的 Rails 应用程序处理。
所以我考虑做这样的事情:
require 'tempfile'
def foo()
# creates a temporary file in tmp/
Tempfile.open('prefix', "#{Rails.root}/tmp") do |f|
f.print('a temp message')
f.flush
send_file(f.path, :x_sendfile => true) # send_file f.path in rails 3
end
end
这个设置有一个问题:文件在发送之前被删除!
一方面,一旦 Tempfile.open
块结束,tempfile
就会删除该文件。另一方面,x-sendfile 使 send_file 调用异步 - 它返回得非常快,因此服务器几乎没有时间发送文件。
我现在最好的解决方案是使用非临时文件(文件而不是临时文件),然后使用 cron 任务定期删除临时文件夹。这有点不雅,因为:
- 我必须使用自己的临时文件命名方案
- 文件在 tmp 文件夹中停留的时间比需要的时间长。
有更好的设置吗?或者,异步 send_file
上是否至少有一个“成功”回调,以便我可以在完成后删除 f ?
多谢。
Some time ago I wrote a question regarding the use of temporary files within a rails app. On thar particular case, I decided to use tempfile
This causes a problem if I also want to use the x-sendfile
directive (as a parameter in Rails 2, or as a configuration option in Rails 3) so that the file sending is handled by my web server directly, not my rails app.
So I thought about doing something like this:
require 'tempfile'
def foo()
# creates a temporary file in tmp/
Tempfile.open('prefix', "#{Rails.root}/tmp") do |f|
f.print('a temp message')
f.flush
send_file(f.path, :x_sendfile => true) # send_file f.path in rails 3
end
end
This setup has one issue: the file is deleted before being sent!
On one hand, tempfile
will delete the file as soon as the Tempfile.open
block is over. On the other, x-sendfile
makes the send_file call asynchronous - it returns very quickly, so the server hardly has time to send the file.
My best possible solution right now involves using non-temporary files (File instead of Tempfile), and then a cron task that erases the temp folder periodically. This is a bit inelegant since:
- I have to use my own tempfile naming scheme
- Files stay on the tmp folder longer than they are needed.
Is there a better setup? Or, is there at least a "success" callback on the asynchronous send_file
, so I can erase f when it's done?
Thanks a lot.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
鉴于 Rails3 在 x-sendfile 可用时使用它,并且无法停用它,因此您不能将 send_file 与 TempFile 等库一起使用。最好的选择是我在问题中提到的一个:使用常规文件,并有一个定期删除旧临时文件的 cron 任务。
编辑:现在使用 maid gem 可以更轻松地处理未使用的文件的删除:
https://github.com/本杰米诺克斯/女仆
Given that Rails3 uses x-sendfile when it is available, and there is no way to deactivate it, you just can't use send_file with a library such as TempFile. The best option is the one I mentioned in the question: use a regular File, and have a cron task that removes old temp files periodically.
EDIT: The removal of unused files has now been easier to deal with with the maid gem:
https://github.com/benjaminoakes/maid
不要将 send_file 放入块中。
然后使用另一个脚本来清理临时文件
don't put send_file in block.
then using another script to cleanup tempfile
file-temp gem 怎么样? https://github.com/djberg96/file-temp
就像zzzhc的答案一样,你需要管理外部清理
How about the file-temp gem? https://github.com/djberg96/file-temp
Like the zzzhc's answer, you would need to manage cleanup externally
您可以取消定义 Tempfile 实例的终结器,以便在实例被销毁时您的文件永远不会被删除,然后让 chron 任务处理它。
You can undefine Tempfile instance's finalizer so that your file never gets deleted when the instance is detroyed and then let the chron task handle it.