【问题标题】:Sinatra 1.3 Streaming w/ Ruby stdout redirection带有 Ruby 标准输出重定向的 Sinatra 1.3 流式传输
【发布时间】:2011-12-23 23:26:35
【问题描述】:

我想使用 Sinatra 在 1.3 中引入的 Streaming 功能以及一些标准输出重定向。它基本上是一个长期运行的工作的实时流输出。我查看了自述文件中的this question 和 Sinatra 流式传输示例。

在 OSX 上运行 1.8.7:

require 'stringio'
require 'sinatra'

$stdout.sync = true

module Kernel
  def capture_stdout
    out = StringIO.new
    $stdout = out
    yield out
  ensure
    $stdout = STDOUT
  end
end

get '/' do
  stream do |out|
    out << "Part one of a three part series... <br>\n"
    sleep 1
    out << "...part two... <br>\n"
    sleep 1
    out << "...and now the conclusion...\n"

    Kernel.capture_stdout do |stream|
        Thread.new do
            until (line = stream.gets).nil? do
               out << line
             end
        end
        method_that_prints_text
    end
  end
end

def method_that_prints_text
    puts "starting long running job..."
    sleep 3
    puts "almost there..."
    sleep 3
    puts "work complete!"
end

所以这段代码正确地打印出前三个字符串,并在 method_that_prints_text 执行时阻塞,并且不向浏览器打印任何内容。我的感觉是 stdout 在第一次调用时是空的,它永远不会输出到输出缓冲区。我不太确定正确的顺序是什么,如果有任何建议,我将不胜感激。

我尝试了上面问题中提到的一些 EventMachine 实现,但无法让它们工作。

更新

我尝试了一些与我在新线程中运行该方法的位置略有不同的方法,并按照here...的描述覆盖该线程的 STDOUT...

而不是上面的Kernel.capture_stdout...

s = StringIO.new

Thread.start do
    Thread.current[:stdout] = s
    method_that_prints_text
end.join

while line = s.gets do
    out << line
end

out << s.string

使用上面链接中列出的ThreadOut 模块,这似乎工作得更好一些。但是它不会流式传输。唯一一次打印到浏览器的是最后一行out &lt;&lt; s.stringStringIO 没有流媒体功能吗?

【问题讨论】:

    标签: ruby streaming sinatra redirect stdout


    【解决方案1】:

    我最终解决了这个问题,发现s.string 随着时间的推移会定期更新,所以我只是在一个单独的线程中捕获了输出,并抓住了差异并将它们流出。看起来好像字符串重定向不像普通的 IO 对象。

    s = StringIO.new
    t = Thread.start do
      Thread.current[:stdout] = s
      method_that_prints_text
      sleep 2
    end
    
    displayed_text = ''
    while t.alive? do
      current_text = s.string
      unless (current_text.eql?(displayed_text))
        new_text = current_text[displayed_text.length..current_text.length]
        out << new_text
        displayed_text = current_text * 1
      end
      sleep 2   
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-20
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多