Тонкий не выводится, когда fork / exec-ed из Ruby - PullRequest
1 голос
/ 14 января 2012

Я пытаюсь запустить thin start 2>&1 в подпроцессе, запустив fork / exec, и я переназначаю STDOUT на канал, чтобы я мог передавать вывод через.

Однако при успешном запуске Thin я не получаю вывод. Когда происходит ошибка, я получаю вывод в неправильном порядке - сначала текст ошибки, затем стандартные сообщения запуска Thin.

Я скопировал код из Foreman, который обрабатывает это правильно. Есть идеи, что происходит?

Код:

reader, writer = IO.pipe
pid = fork do
  Process.setpgrp
  trap("INT", "IGNORE")
  $stdout.reopen writer
  reader.close
  exec("thin start 2>&1")
end
Process.detach pid
until reader.eof?
  puts reader.gets
end

1 Ответ

3 голосов
/ 14 января 2012

Данные, отправленные на $stdout, не распечатываются немедленно - они буферизируются. С другой стороны, $stderr не буферизируется, и когда вы пишете в него, вы сразу видите результаты. Давайте посмотрим на минимальный пример.

STDOUT.puts :stdout
STDERR.puts :stderr

Сохраните его как test.rb и замените thin start на ruby test.rb. Скорее всего, stdout будет напечатано после stderr. Чтобы исправить это, нам нужно использовать метод IO#sync=

STDOUT.sync = true
STDOUT.puts :stdout
STDERR.puts :stderr

Теперь stdout будет печататься синхронно, как и stderr, и результирующий порядок печатаемых строк должен быть интуитивно понятным.

Первоначальный недостаток вывода вашего ребенка. Тонкий процесс может быть вызван тем, что ребенок не сбрасывает данные в STDOUT. Первый фрагмент данных, записанный в STDERR, вызывает сброс STDOUT. Попробуйте добавить STDOUT.sync = true где-нибудь в источниках вашего приложения или Thin и посмотрите, помогло ли это.

См. Также обсуждение на ruby-forum.com под названием захват вывода в режиме реального времени .

...