我正在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中安排一个调用以发送块。您的代码的问题在于,它阻塞了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
一旦事件机器准备就绪,它将立即读取一个块,而不会阻塞事件循环。当然,在这种情况下,s3_object.read一次只需要返回一个块。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句