Как я могу создать демона с помощью 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

Другие вопросы по тегам