У меня есть следующий тестовый файл конфигурации для службы выскочки, работающей в Ubuntu 14.04:
expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
script
ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 }" > /tmp/upstart_test.log
end script
Встроенный скрипт ruby просто спит в течение 5 секунд (для имитации загрузки), затем отправляет себе сигнал STOP, чтобы уведомить Upstart, что он готов, а затем несколько раз печатает «работает» (чтобы имитировать выполнение какой-либо службы). Вау, круто. Такой простой.
Проблема в том, что когда я запускаю эту "службу" с start fake-service
, эта команда зависает (ожидая завершения запуска службы), и процесс завершается в остановленном состоянии, которое Upstart никогда не подтверждает и не отправляет «CONT».
Что дает??
Я обнаружил, что если в конфигурационном файле я использую exec вместо блока сценария для запуска команды, запускающей «демон», он работает нормально:
expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
exec ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 }" > /tmp/upstart_test.log
Однако, если я включу в скрипт вилку (в которой весь смысл использования expect stop
в первую очередь подумал - помочь Upstart легко определить PID основного процесса):
expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
exec ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; fork { Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 } }; Process.wait" > /tmp/upstart_test.log
В документации Upstart есть предупреждение об использовании expect с блоками сценария, но в нем конкретно говорится о том, что выполнение нескольких команд в блоке является проблематичным, потому что он не знает, какую из них смотреть. В этом случае я выполняю только одну команду ... так что это не помогает.
Оказывается, я считаю, что мое понимание expect stop
было неверно! Я думал, как я уже говорил выше, что он был использован (как и другие expect
stanzas), чтобы Upstart мог легко определить PID основного процесса.
Теперь, когда я перечитал документацию, я полагаю, что это означает, где говорится: «Указывает, что основной процесс задания вызовет сигнал SIGSTOP, чтобы указать, что он готов», - это то, что оригинал процесс, который запускается выскочкой, должен поднять сигнал STOP, и этот сигнал используется только чтобы определить, когда работа будет готова. Так это expect
строфа не связана с двумя другими, которые используются для определения основного PID задания, содержащего вилки.
И причина, по которой он не работает для блока сценария, заключается в том, что сам блок сценария создает новую оболочку для запуска своего содержимого, поэтому основной процесс фактически является родителем любой команды, выполняемой внутри блока.
Теперь все становится намного понятнее :)