1.3で導入されたSinatraのストリーミング機能を、標準出力リダイレクトと組み合わせて使用したいと思います。これは、基本的に長時間実行されるジョブのライブストリーミング出力になります。私はthis questionとREADMEのSinatraストリーミングサンプルを調べました。 OSX上で1.8.7を実行Sinatra 1.3ストリーミング(Ruby標準出力リダイレクト)
:
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
だから、コードのこのビットが適切に最初の3つの文字列を出力し、ブロックmethod_that_prints_text
実行しながら、ブラウザには何も印刷されません。最初の呼び出しではstdoutが空であり、出力バッファには出力されません。私は、適切な注文がどんなものであろうと確信しておらず、何か提案を感謝するでしょう。
上記の質問に記載されているEventMachine実装のいくつかを試しましたが、動作させることができませんでした。
UPDATE
私は新しいスレッドでメソッドを実行していたところへ、わずかに別の何かを試みたが、hereを説明するように、そのスレッドのためのSTDOUTを上書き...
の代わりに上記Kernel.capture_stdout
ThreadOut
モジュール付き。
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
、これは少し良く動作しているようです。しかしそれは流れません。何かがブラウザに印刷される唯一の時間は、最終行out << s.string
です。 StringIO
にはストリーム機能がありませんか?