我在 Thin 上运行 Sinatra 应用程序。
下面是代码的简化外观:
class StreamApp < Sinatra::Base
get "/" do
s3_object = # large S3 object (not loaded into memory)
stream do |out|
s3_object.read do |chunk|
out << chunk
end
end
end
end
随着流式传输的进行,盒子上的内存开始上升到达到最大值的程度,进程就此结束。
我读过 2009 年的文章,说这是 EventMachine 和 Rack 在整个响应完成之前缓冲数据的问题。
有没有人见过这个问题或找到解决方法?
最佳答案
sinatra 中的流式处理在 eventmachine 下的工作方式是每次调用
out << chunk
sinatra 在 eventmachine 中安排一个调用来发送 block 。您的代码的问题在于它会阻塞 eventmachines 事件循环,直到读取整个文件并完成读取。因此,在整个数据都在内存中之前,不会发送任何内容。
这可以通过做类似的事情来解决:
get "/" do
s3_object = # large S3 object (not loaded into memory)
stream :keep_open do |out|
reader = lambda {
chunk = s3_object.read
break if chunk == nil
out << chunk
EM::next_tick &reader
}
reader.call
end
end
这将在 eventmachine 准备就绪时立即读取一个 block ,而不会阻塞事件循环。当然在这种情况下 s3_object.read 一次只需要返回一个 block 。
关于ruby - 在 Sinatra 和 Thin 上下载大文件时内存消耗高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24251886/