ruby - 在 Sinatra 和 Thin 上下载大文件时内存消耗高

标签 ruby sinatra rack thin eventmachine

我在 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/

相关文章:

ruby-on-rails - NameError - 未初始化的常量 Zip

ruby - 更改多个字符串、大写、小写等的一行代码?

ruby-on-rails - Rails 中的手动请求调度

ruby-on-rails - rails 查询超时::错误:执行已过期

ruby-on-rails - rails : CoffeeScript is not defined on new Application

ruby-on-rails - Rails + Sinatra 应用分享会

ruby - Sinatra 助手伪造请求

ruby - 加载错误 : no such file to load -- dm-sqlite-adapter

ruby - 使用 Rack 将网络上传流式传输到套接字

ruby - { :x => 1} and {:x => 1, :y => nil} in ruby? 之间有什么区别吗