Как я могу создать демона с помощью Thor (ruby)?
Я хотел бы использовать популярный камень Thor для создания демонизированной задачи. Мой класс Тора выглядит так:
require 'rubygems'
require 'daemons'
require 'thor'
class CLI < Thor
desc "start", "Startup the App"
method_option :daemonize, :aliases => "-d", :default => false, :type => :boolean, :banner => "Run as daemon"
def start
run_app(options[:daemonize])
end
desc "stop", "Stop the daemon"
def stop
stop_app
end
no_tasks {
def run_app(run_as_daemon)
# Run the application code
Daemons.daemonize if run_as_daemon
# loop until stopped or interrupted
# ...
end
def stop_app
#stop the app
end
}
end
Итак, здесь я настроил базовый класс с двумя задачами: запуск и остановка. Я также в настоящее время использую драгоценный камень Демонов, но это не обязательно. Часть, с которой я борюсь, заключается в том, что, когда это приложение запускается как run_thor_app.rb start, все работает нормально. Очевидно, что в этом случае задача остановки не нужна. Но когда я запускаю "run_thor_app.rb start -d", приложение запускается до тех пор, пока не запустится Daemons.daemonize, а затем закроется. Проверка запущенных процессов показывает, что ничего не работает в фоновом режиме.
Даже если бы что-то работало, я бы не знал, как подойти к задаче остановки. Например, как вы обнаруживаете, что приложение работает как демон, и останавливаете его. Я посмотрел на Daemons::Monitor, но в документации не ясно, как это работает, и когда я попробовал, это не сработало.
Мне кажется, что это было бы хорошим вариантом использования чего-то, что встроено в Thor, но поиск по коду на github мне ничего не показал. Может быть, я просто где-то пропустил. В любом случае, я думаю, что было бы хорошо документировать лучшие практики или шаблоны для работы с демонами с помощью Thor, чтобы другие могли на них ссылаться.
1 ответ
Обычно вы управляете процессами демона, когда они записывают свой PID в файл. Это позволяет другому процессу обнаружить PID демона и уничтожить его (или отправить какой-либо другой сигнал).
Ваш код должен работать. Я попробовал сценарий голой кости, который использовал deamons
драгоценный камень, и мне потребовалось несколько попыток, пока я не нашел деамонизированный процесс. Я подумал, что он получит то же имя, что и родительский процесс, или что-то похожее, но вместо этого его имя было "я". Помните, что демонизированный процесс больше не будет писать в STDOUT
,
В любом случае, попробуйте это:
# set up everything
# then daemonize
Daemons.daemonize
# and write a pid file
File.open('/tmp/mydaemon.pid', 'w') { |f| f.puts(Process.pid) }
loop do
# do something
# this loop is important, if the script ends the daemon dies
end
и проверить /tmp/mydaemon.pid
файл для PID. Тогда беги ps ax | grep x
где х это PID. Бежать cat /tmp/mydaemon.pid
| xargs kill`, чтобы убить демона.
я думаю daemons
У gem есть несколько помощников для управления PidFiles. PidFile
в http://rubydoc.info/gems/daemons/1.1.0/frames