【问题标题】:High memory consumption downloading large files on Sinatra and Thin在 Sinatra 和 Thin 上下载大文件会消耗大量内存
【发布时间】:2014-08-06 18:17:06
【问题描述】:

我正在 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 缓冲数据直到整个响应完成的问题。

有没有人看到这个问题或找到解决方法?

【问题讨论】:

    标签: ruby sinatra rack thin eventmachine


    【解决方案1】:

    sinatra 中的流式处理在 eventmachine 下的工作方式是每次调用 out &lt;&lt; chunk sinatra 在 eventmachine 中安排调用以发送块。您的代码的问题是它阻塞了 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 准备好后立即读取一个块,而不会阻塞事件循环。当然在这种情况下 s3_object.read 只需要一次返回一个块。

    【讨论】:

    • 嗯,有道理。我将尝试重新创建它,因为这是很久以前的一个问题,我们已经不再维护此代码。不过,我仍然想看看这是否能解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2012-11-14
    • 2022-12-06
    • 2022-01-16
    • 2014-01-04
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多