我在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缓存数据的问题,直到整个响应完成。
有没有人看过这个问题或找到了解决方法?
答案 0 :(得分:2)
在sinatra中流式传输的方式在eventmachine下运行是为了每次调用
out << chunk
sinatra计划在eventmachine中调用以发送块。您的代码的问题在于它会阻止事件处理事件循环,直到读取整个文件并完成读取。因此,除了整个数据都在内存中之外,不会发送任何内容。
这可以通过以下方式解决:
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只需要返回一个块。