Giter VIP home page Giter VIP logo

daemons's Introduction

Ruby Daemons

Build StatusCode ClimateTest Coverage

Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server) to be run as a daemon and to be controlled by simple start/stop/restart commands.

If you want, you can also use daemons to run blocks of ruby code in a daemon process and to control these processes from the main application.

Besides this basic functionality, daemons offers many advanced features like exception backtracing and logging (in case your ruby script crashes) and monitoring and automatic restarting of your processes if they crash.

Basic Usage

You can use Daemons in four different ways:

1. Create wrapper scripts for your server scripts or applications

Layout: suppose you have your self-written server myserver.rb:

# this is myserver.rb
# it does nothing really useful at the moment

loop do
  sleep(5)
end

To use myserver.rb in a production environment, you need to be able to run myserver.rb in the background (this means detach it from the console, fork it in the background, release all directories and file descriptors).

Just create myserver_control.rb like this:

# this is myserver_control.rb
require 'daemons'

Daemons.run('myserver.rb')

And use it like this from the console:

$ ruby myserver_control.rb start
    (myserver.rb is now running in the background)
$ ruby myserver_control.rb restart
    (...)
$ ruby myserver_control.rb stop

For testing purposes you can even run myserver.rb without forking in the background:

$ ruby myserver_control.rb run

An additional nice feature of Daemons is that you can pass additional arguments to the script that should be daemonized by seperating them by two hyphens:

$ ruby myserver_control.rb start -- --file=anyfile --a_switch another_argument

2. Create wrapper scripts that include your server procs

Layout: suppose you have some code you want to run in the background and control that background process from a script:

# this is your code
# it does nothing really useful at the moment

loop do
  sleep(5)
end

To run this code as a daemon create myproc_control.rb like this and include your code:

# this is myproc_control.rb
require 'daemons'

Daemons.run_proc('myproc.rb') do
  loop do
    sleep(5)
  end
end

And use it like this from the console:

$ ruby myproc_control.rb start
    (myproc.rb is now running in the background)
$ ruby myproc_control.rb restart
    (...)
$ ruby myproc_control.rb stop

For testing purposes you can even run myproc.rb without forking in the background:

$ ruby myproc_control.rb run

3. Control a bunch of daemons from another application

Layout: you have an application my_app.rb that wants to run a bunch of server tasks as daemon processes.

# this is my_app.rb
require 'daemons'

task1 = Daemons.call(:multiple => true) do
  # first server task

  loop do
    conn = accept_conn()
    serve(conn)
  end
end

task2 = Daemons.call do
  # second server task

  loop do
    something_different()
  end
end

# the parent process continues to run

# we can even control our tasks, for example stop them
task1.stop
task2.stop

exit

4. Daemonize the currently running process

Layout: you have an application my_daemon.rb that wants to run as a daemon (but without the ability to be controlled by daemons via start/stop commands)

# this is my_daemons.rb
require 'daemons'

# Initialize the app while we're not a daemon
init()

# Become a daemon
Daemons.daemonize

# The server loop
loop do
  conn = accept_conn()
  serve(conn)
end

For further documentation, refer to the module documentation of Daemons.

Displaying daemon status

When daemonizing a process using a wrapper script, as examples 1 and 2 above, the status can be shown using

$ ruby myproc_control.rb status

By default this will display whether or not the daemon is running and, if it is, its PID.

A custom message can be shown with

def custom_show_status(app)
  # Display the default status information
  app.default_show_status

  puts
  puts "PS information"
  system("ps -p #{app.pid.pid.to_s}")

  puts
  puts "Size of log files"
  system("du -hs /path/to/logs")
end

Daemons.run('myserver.rb', { show_status_callback: :custom_show_status })

Documentation

Documentation can be found at http://www.rubydoc.info/gems/daemons.

Author

Written 2005-2021 by Thomas Uehlinger, 2014-2016 by Aaron Stone.

daemons's People

Contributors

amatsuda avatar andreasbomholtz avatar c960657 avatar dependabot[bot] avatar dsinn avatar fnordfish avatar inecas avatar intentionaccident avatar kamipo avatar kzkn avatar lmrodriguezr avatar loe avatar lzap avatar olleolleolle avatar petergoldstein avatar philister avatar rlue avatar sephvelut avatar sodabrew avatar tardate avatar tastypi avatar thuehlinger avatar tobithiel avatar willianveiga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

daemons's Issues

Why parent process does not care about child

Hello! Andrew here!
I have a question about the line

pid = rd.read.to_i

Here we got pid from child throw pipe. But then we do not call Process.waitpid / Process.detach for it. Why?

Every time when child process terminated in docker container I get "zombie" process, because tmppid and pid are diffirent.

Here I set log:

diff --git a/lib/daemons/daemonize.rb b/lib/daemons/daemonize.rb
index bce7246..e9ec5ca 100644
--- a/lib/daemons/daemonize.rb
+++ b/lib/daemons/daemonize.rb
@@ -49,6 +49,9 @@ module Daemonize
       pid = rd.read.to_i
       rd.close
 
+      logger = Logger.new('/tmp/daemons.log')
+      logger.info [pid, tmppid].inspect
+
       Process.waitpid(tmppid)
 
       return pid
cat /tmp/daemons.log

# Logfile created on 2018-05-29 13:27:52 +0500 by logger.rb/56504
[38, 35]

Regards, Andrew!

run many workers

hello there.
I try to run 2 my workers:
["first_worker.rb", "second_worker.rb"].each { |worker| Daemons.run(worker) }
But is running only first. Why? How can i run all my workers?

Failure to find pid files when status or stop is specified without a number argument

If I start a daemon with '-n 5', I get 5 processes and 5 pid files.

However, if I then simply type "status", no processes are found. Consequently, "stop" fails to work as well.

If I run "stop -n 5", (or -n 100 for that matter), daemons does correctly find the processes.

Is this the intended behavior? Presumably 'stop' and 'status' should both work without a number being specified.

Permissions on created folders different between 1.0.10 and 1.2.3

I'm using the daemons gem in combination with delayed_job. After upgrading the daemons gem from version 1.0.10 to 1.2.3 I was experiencing a strange behavior:

Folders created with FileUtils.mkdir_p(dir) got a permission mask, so that the user running the processes couldn't write into that folder. I got permission denied errors. After debugging and changing the permissions to 0755, the process was running fine again.

Rolling back to version 1.0.10, everything works as expected.

Is there any explanation about this behavior? We're running a Debian based setup.

Run script files in background (as daemons)

Hi.

For some reason I'm not fully understanding the usage of the library for some cases.
My use case is the following:

  • I have a main process (called scheduler), this scheduler knows the location of a script that performs a certain task.
  • My goal is to call such script as a completely separated script file (using the :script argument).
  • The scheduler want to run several times (virtually infinitely) the script file.
  • I do not need to keep track of the new(s) workers that get created, just create and run them as soon as I need them.

What's the better approach to achieve this behavior?

Example code:

require 'daemons'
require_relative 'parser.rb'

def get_config(index = 0)
  name = 'worker' + rand(0..Time.now.to_i).to_s
  script_argv_array = [
      '--my_named_arg', 'my_named_arg_value'
  ]
  daemon_argv_array = ['start', '--']
  argv_array = daemon_argv_array.concat script_argv_array
  {
      :app_name => name,
      :ARGV => argv_array,
      :dir => '/tmp',
      :dir_mode => :normal,
      :force => true,
      :mode => :load,
      :multiple => true,
      :name => name
  }
end

1.times do |index|
  config = get_config(index)
  puts("config=#{config}")
  begin
    process = Daemons.run(script = __dir__ + '/infinite_loop.rb', options = config)
    puts("process=#{process}")
  rescue Exception => e
    puts(e.to_s)
    puts(e.message)
    puts(e.backtrace)
    break
  end
  puts("Done")
end

puts("Scheduler is done")

I.e. This example code would throw an exception and child processes won't get PPID=1

Thanks in advance and congratulations for the library :)

NoMethodError: undefined method `positive?' for 20:Fixnum

Trying to run RAILS_ENV=production script/delayed_job -n2 restart
fails with

/home/ubuntu/crm/shared/bundle/ruby/2.2.0/gems/daemons-1.4.1/lib/daemons/application.rb:409:in `wait_and_retry_kill_harder': undefined method `positive?' for 20:Fixnum (NoMethodError)
        from /home/ubuntu/crm/shared/bundle/ruby/2.2.0/gems/daemons-1.4.1/lib/daemons/application.rb:386:in `stop'
        from /home/ubuntu/crm/shared/bundle/ruby/2.2.0/gems/daemons-1.4.1/lib/daemons/application_group.rb:181:in `block (2 levels) in stop_all'

This is my Gemfile.lock

GIT
  remote: https://github.com/dwaynemac/omniauth-hubspot
  revision: 3eaa1efca8eafa2aedaccd844216e2a98ab50299
  specs:
    omniauth-hubspot (0.1.1)
      oauth2
      omniauth
      omniauth-oauth2

GIT
  remote: https://github.com/zebitex/aws-ses.git
  revision: 65e1ff1c3c2031b243f773cb9e61df6e49db71dd
  ref: 78-sigv4-problem
  specs:
    aws-ses (0.7.1)
      builder
      mail (> 2.2.5)
      mime-types
      xml-simple

GEM
  remote: http://rubygems.org/
  specs:
    RedCloth (4.3.2)
    accounts_client (0.3.3)
      gravtastic
      logical_model (>= 0.7.1)
      railties (>= 3.1)
    actionmailer (4.2.11.3)
      actionpack (= 4.2.11.3)
      actionview (= 4.2.11.3)
      activejob (= 4.2.11.3)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 1.0, >= 1.0.5)
    actionpack (4.2.11.3)
      actionview (= 4.2.11.3)
      activesupport (= 4.2.11.3)
      rack (~> 1.6)
      rack-test (~> 0.6.2)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (4.2.11.3)
      activesupport (= 4.2.11.3)
      builder (~> 3.1)
      erubis (~> 2.7.0)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.3)
    activejob (4.2.11.3)
      activesupport (= 4.2.11.3)
      globalid (>= 0.3.0)
    activemodel (4.2.11.3)
      activesupport (= 4.2.11.3)
      builder (~> 3.1)
    activerecord (4.2.11.3)
      activemodel (= 4.2.11.3)
      activesupport (= 4.2.11.3)
      arel (~> 6.0)
    activerecord-session_store (1.1.3)
      actionpack (>= 4.0)
      activerecord (>= 4.0)
      multi_json (~> 1.11, >= 1.11.2)
      rack (>= 1.5.2, < 3)
      railties (>= 4.0)
    activesupport (4.2.11.3)
      i18n (~> 0.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    activity_stream_client (0.1.0)
      logical_model (= 0.7.1)
      railties (>= 3.1)
    airbrussh (1.4.0)
      sshkit (>= 1.6.1, != 1.7.0)
    appsignal (3.0.21)
      rack
    arel (6.0.4)
    attendance_client (0.0.4)
      logical_model (>= 0.5.13)
      railties (>= 3.1)
    aws-eventstream (1.1.1)
    aws-partitions (1.493.0)
    aws-sdk-core (3.119.1)
      aws-eventstream (~> 1, >= 1.0.2)
      aws-partitions (~> 1, >= 1.239.0)
      aws-sigv4 (~> 1.1)
      jmespath (~> 1.0)
    aws-sdk-sns (1.44.0)
      aws-sdk-core (~> 3, >= 3.119.0)
      aws-sigv4 (~> 1.1)
    aws-sigv4 (1.2.4)
      aws-eventstream (~> 1, >= 1.0.2)
    bcrypt (3.1.16)
    binding_of_caller (1.0.0)
      debug_inspector (>= 0.0.1)
    bootstrap-datepicker-rails (1.9.0.1)
      railties (>= 3.0)
    builder (3.2.4)
    bullet (5.7.6)
      activesupport (>= 3.0.0)
      uniform_notifier (~> 1.11.0)
    byebug (10.0.2)
    calculus (0.2.0)
    cancan (1.6.10)
    capistrano (3.16.0)
      airbrussh (>= 1.0.0)
      i18n
      rake (>= 10.0.0)
      sshkit (>= 1.9.0)
    capistrano-bundler (2.0.1)
      capistrano (~> 3.1)
    capistrano-ext (1.2.1)
      capistrano (>= 1.0.0)
    capistrano-rails (1.6.1)
      capistrano (~> 3.1)
      capistrano-bundler (>= 1.1, < 3)
    capistrano-rbenv (2.2.0)
      capistrano (~> 3.1)
      sshkit (~> 1.3)
    capistrano3-unicorn (0.2.1)
      capistrano (~> 3.1, >= 3.1.0)
    carrierwave (1.3.2)
      activemodel (>= 4.0.0)
      activesupport (>= 4.0.0)
      mime-types (>= 1.16)
      ssrf_filter (~> 1.0)
    chartkick (3.4.2)
    coffee-rails (4.2.2)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0)
    coffee-script (2.4.1)
      coffee-script-source
      execjs
    coffee-script-source (1.12.2)
    commonjs (0.2.7)
    concurrent-ruby (1.1.10)
    connection_pool (2.2.5)
    contacts_client (0.0.54.pre.c)
      logical_model (>= 0.6.5)
      railties (>= 3.1)
    crass (1.0.6)
    daemons (1.4.1)
    dalli (2.6.4)
    dalli-delete-matched (1.3.1)
      dalli
    database_cleaner (1.99.0)
    debug_inspector (1.1.0)
    delayed_job (4.1.10)
      activesupport (>= 3.0, < 8.0)
    delayed_job_active_record (4.1.7)
      activerecord (>= 3.0, < 8.0)
      delayed_job (>= 3.0, < 5)
    delayed_job_web (1.4.4)
      activerecord (> 3.0.0)
      delayed_job (> 2.0.3)
      rack-protection (>= 1.5.5)
      sinatra (>= 1.4.4)
    devise (3.4.1)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 3.2.6, < 5)
      responders
      thread_safe (~> 0.1)
      warden (~> 1.2.3)
    diff-lcs (1.5.0)
    draper (2.1.0)
      actionpack (>= 3.0)
      activemodel (>= 3.0)
      activesupport (>= 3.0)
      request_store (~> 1.0)
    erubis (2.7.0)
    ethon (0.6.3)
      ffi (>= 1.3.0)
      mime-types (~> 1.18)
    excon (0.91.0)
    execjs (2.8.1)
    factory_bot (4.11.1)
      activesupport (>= 3.0.0)
    factory_bot_rails (4.11.1)
      factory_bot (~> 4.11.1)
      railties (>= 3.0.0)
    fancybox-rails (0.3.1)
      railties (>= 3.1.0)
    faraday (0.17.4)
      multipart-post (>= 1.2, < 3)
    ffi (1.12.2)
    figaro (1.2.0)
      thor (>= 0.14.0, < 2)
    fnz_client (0.0.5)
      logical_model (>= 0.5.11)
      railties (>= 3.1)
    fog-aws (3.13.0)
      fog-core (~> 2.1)
      fog-json (~> 1.1)
      fog-xml (~> 0.1)
    fog-core (2.2.4)
      builder
      excon (~> 0.71)
      formatador (~> 0.2)
      mime-types
    fog-json (1.2.0)
      fog-core
      multi_json (~> 1.10)
    fog-xml (0.1.4)
      fog-core
      nokogiri (>= 1.5.11, < 2.0.0)
    foreman (0.87.2)
    formatador (0.3.0)
    formtastic (3.0.0)
      actionpack (>= 3.2.13)
    genderize-io (1.4.0)
      typhoeus
    get_process_mem (0.2.7)
      ffi (~> 1.0)
    globalid (0.4.2)
      activesupport (>= 4.2.0)
    gravtastic (3.2.6)
    hashie (3.6.0)
    i18n (0.9.5)
      concurrent-ruby (~> 1.0)
    i18n-js (3.0.0)
      i18n (~> 0.6, >= 0.6.6)
    jmespath (1.6.0)
    jquery-fileupload-rails (1.0.0)
      actionpack (>= 3.1)
      railties (>= 3.1)
      sassc
    jquery-rails (4.4.0)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    jquery-ui-rails (6.0.1)
      railties (>= 3.2.16)
    jwt (2.3.0)
    kaminari (1.2.2)
      activesupport (>= 4.1.0)
      kaminari-actionview (= 1.2.2)
      kaminari-activerecord (= 1.2.2)
      kaminari-core (= 1.2.2)
    kaminari-actionview (1.2.2)
      actionview
      kaminari-core (= 1.2.2)
    kaminari-activerecord (1.2.2)
      activerecord
      kaminari-core (= 1.2.2)
    kaminari-core (1.2.2)
    kgio (2.11.4)
    less (2.6.0)
      commonjs (~> 0.2.7)
    less-rails (2.8.0)
      actionpack (>= 4.0)
      less (~> 2.6.0)
      sprockets (> 2, < 4)
      tilt
    less-rails-bootstrap (3.3.5.0)
      less-rails (>= 2.6, <= 2.8)
    libv8 (3.16.14.19)
    logical_model (0.7.1)
      activemodel
      activesupport
      ethon (= 0.6.3)
      kaminari (~> 1.2.1)
      typhoeus (= 0.6.4)
    loofah (2.19.0)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    mailing_client (0.0.5)
      logical_model (>= 0.5.5)
      railties (>= 3.1)
    messaging_client (0.3.0)
      aws-sdk-sns (~> 1)
      logical_model (= 0.7.1)
      railties (>= 3.1)
    mime-types (1.25.1)
    mini_magick (4.11.0)
    mini_mime (1.1.2)
    mini_portile2 (2.4.0)
    minitest (5.15.0)
    multi_json (1.15.0)
    multi_xml (0.6.0)
    multipart-post (2.1.1)
    mysql2 (0.4.10)
    net-http-persistent (3.1.0)
      connection_pool (~> 2.2)
    net-scp (3.0.0)
      net-ssh (>= 2.6.5, < 7.0.0)
    net-ssh (5.2.0)
    nokogiri (1.9.1)
      mini_portile2 (~> 2.4.0)
    nokogumbo (2.0.5)
      nokogiri (~> 1.8, >= 1.8.4)
    oauth2 (1.4.7)
      faraday (>= 0.8, < 2.0)
      jwt (>= 1.0, < 3.0)
      multi_json (~> 1.3)
      multi_xml (~> 0.5)
      rack (>= 1.2, < 3)
    omniauth (1.4.2)
      hashie (>= 1.2, < 4)
      rack (>= 1.0, < 3)
    omniauth-mailchimp (2.1.0)
      omniauth (~> 1.0)
      omniauth-oauth2
    omniauth-notion (0.0.2)
      omniauth (~> 1.0)
    omniauth-oauth2 (1.5.0)
      oauth2 (~> 1.1)
      omniauth (~> 1.2)
    orm_adapter (0.5.0)
    padma-assets (0.3.20)
      railties (>= 3.1)
    pg (1.2.3)
    power_assert (2.0.1)
    protected_attributes (1.1.4)
      activemodel (>= 4.0.1, < 5.0)
    rack (1.6.13)
    rack-cache (1.7.1)
      rack (>= 0.4)
    rack-cors (1.0.6)
      rack (>= 1.6.0)
    rack-protection (1.5.5)
      rack
    rack-test (0.6.3)
      rack (>= 1.0)
    rails (4.2.11.3)
      actionmailer (= 4.2.11.3)
      actionpack (= 4.2.11.3)
      actionview (= 4.2.11.3)
      activejob (= 4.2.11.3)
      activemodel (= 4.2.11.3)
      activerecord (= 4.2.11.3)
      activesupport (= 4.2.11.3)
      bundler (>= 1.3.0, < 2.0)
      railties (= 4.2.11.3)
      sprockets-rails
    rails-deprecated_sanitizer (1.0.4)
      activesupport (>= 4.2.0.alpha)
    rails-dom-testing (1.0.9)
      activesupport (>= 4.2.0, < 5.0)
      nokogiri (~> 1.6)
      rails-deprecated_sanitizer (>= 1.0.1)
    rails-html-sanitizer (1.4.3)
      loofah (~> 2.3)
    rails_refactor (1.4.6)
    railties (4.2.11.3)
      actionpack (= 4.2.11.3)
      activesupport (= 4.2.11.3)
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    raindrops (0.20.0)
    rake (11.3.0)
    rb-fsevent (0.11.1)
    rb-inotify (0.10.1)
      ffi (~> 1.0)
    redcarpet (3.5.1)
    ref (2.0.0)
    request_store (1.5.1)
      rack (>= 1.4)
    responders (2.4.1)
      actionpack (>= 4.2.0, < 6.0)
      railties (>= 4.2.0, < 6.0)
    rexml (3.2.5)
    rinku (2.0.6)
    rspec-core (3.11.0)
      rspec-support (~> 3.11.0)
    rspec-expectations (3.11.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.11.0)
    rspec-its (1.3.0)
      rspec-core (>= 3.0.0)
      rspec-expectations (>= 3.0.0)
    rspec-mocks (3.11.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.11.0)
    rspec-rails (4.1.2)
      actionpack (>= 4.2)
      activesupport (>= 4.2)
      railties (>= 4.2)
      rspec-core (~> 3.10)
      rspec-expectations (~> 3.10)
      rspec-mocks (~> 3.10)
      rspec-support (~> 3.10)
    rspec-support (3.11.0)
    ruby-ole (1.2.12.2)
    sanitize (5.2.3)
      crass (~> 1.0.2)
      nokogiri (>= 1.8.0)
      nokogumbo (~> 2.0)
    sass (3.7.4)
      sass-listen (~> 4.0.0)
    sass-listen (4.0.0)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
    sass-rails (5.0.7)
      railties (>= 4.0.0, < 6)
      sass (~> 3.1)
      sprockets (>= 2.8, < 4.0)
      sprockets-rails (>= 2.0, < 4.0)
      tilt (>= 1.1, < 3)
    sassc (2.4.0)
      ffi (~> 1.9)
    select2-rails (4.0.13)
    shoulda (4.0.0)
      shoulda-context (~> 2.0)
      shoulda-matchers (~> 4.0)
    shoulda-context (2.0.0)
    shoulda-kept-assign-to (1.1.0)
      shoulda-matchers (>= 2.1.0)
    shoulda-matchers (4.0.1)
      activesupport (>= 4.2.0)
    sinatra (1.4.8)
      rack (~> 1.5)
      rack-protection (~> 1.4)
      tilt (>= 1.3, < 3)
    spreadsheet (1.3.0)
      ruby-ole
    sprockets (3.0.0)
      rack (~> 1.0)
    sprockets-rails (3.2.2)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    sshkit (1.21.2)
      net-scp (>= 1.1.2)
      net-ssh (>= 2.8.0)
    ssrf_filter (1.0.7)
    stripe (4.24.0)
      faraday (~> 0.13)
      net-http-persistent (~> 3.0)
    subcontractor (0.6.1)
    test-unit (3.5.3)
      power_assert
    therubyracer (0.12.3)
      libv8 (~> 3.16.14.15)
      ref
    thor (1.2.1)
    thread_safe (0.3.6)
    tilt (2.0.10)
    typhoeus (0.6.4)
      ethon (~> 0.6.0)
    tzinfo (1.2.10)
      thread_safe (~> 0.1)
    uglifier (3.2.0)
      execjs (>= 0.3.0, < 3)
    unicorn (6.1.0)
      kgio (~> 2.6)
      raindrops (~> 0.7)
    unicorn-worker-killer (0.4.5)
      get_process_mem (~> 0)
      unicorn (>= 4, < 7)
    uniform_notifier (1.11.0)
    warden (1.2.7)
      rack (>= 1.0)
    web-console (2.3.0)
      activemodel (>= 4.0)
      binding_of_caller (>= 0.7.2)
      railties (>= 4.0)
      sprockets-rails (>= 2.0, < 4.0)
    xml-simple (1.1.9)
      rexml
    yard (0.8.7.6)
    yard-restful (1.2.4)
      yard (~> 0.8.3)

PLATFORMS
  ruby

DEPENDENCIES
  RedCloth
  accounts_client (= 0.3.3)
  activerecord-session_store
  activity_stream_client (>= 0.0.15)
  appsignal
  attendance_client (= 0.0.4)
  aws-ses!
  bootstrap-datepicker-rails
  bullet (~> 5.7.6)
  byebug
  calculus
  cancan (~> 1.6.7)
  capistrano (~> 3.1)
  capistrano-bundler
  capistrano-ext
  capistrano-rails (~> 1.1)
  capistrano-rbenv
  capistrano3-unicorn
  carrierwave
  chartkick
  coffee-rails (~> 4.2.2)
  contacts_client (= 0.0.54.pre.c)
  daemons
  dalli (= 2.6.4)
  dalli-delete-matched
  database_cleaner
  delayed_job_active_record (= 4.1.7)
  delayed_job_web
  devise (= 3.4.1)
  draper (~> 2.1)
  execjs
  factory_bot_rails
  fancybox-rails
  faraday (~> 0.8)
  figaro
  fnz_client (~> 0.0.5)
  fog-aws
  foreman
  formtastic (~> 3.0.0)
  genderize-io (~> 1.4)
  i18n (= 0.9.5)
  i18n-js (= 3.0.0)
  jquery-fileupload-rails
  jquery-rails
  jquery-ui-rails
  less-rails-bootstrap
  logical_model (>= 0.6.6)
  mailing_client (~> 0.0.5)
  messaging_client (~> 0.2)
  mini_magick
  mysql2 (= 0.4.10)
  nokogiri (= 1.9.1)
  omniauth (= 1.4.2)
  omniauth-hubspot!
  omniauth-mailchimp
  omniauth-notion
  padma-assets (= 0.3.20)
  pg
  protected_attributes
  rack-cache (= 1.7.1)
  rack-cors
  rails (= 4.2.11.3)
  rails_refactor
  rake (< 12)
  redcarpet
  responders (~> 2.0)
  rinku
  rspec-its
  rspec-rails
  sanitize
  sass-rails (~> 5.0.0)
  select2-rails (~> 4.0.0)
  shoulda
  shoulda-kept-assign-to
  spreadsheet
  sprockets (= 3.0.0)
  stripe (~> 4.24)
  subcontractor (= 0.6.1)
  test-unit
  therubyracer
  uglifier (~> 3.2)
  unicorn
  unicorn-worker-killer
  web-console (~> 2.0)
  yard (~> 0.8.3)
  yard-restful

RUBY VERSION
   ruby 2.2.6p396

BUNDLED WITH
   1.17.3

Make daemon start silent

Hello,

Is there any supported option (or plans to support an option) to tell daemons to run quietly? Usually the "...: process with pid ... started." and "...: trying to stop process with pid..." messages are very useful, but in some cases (e.g. unit testing) it would be great if I could turn them off. It's not a high-priority enhancement, but I would imagine is not very hard to implement.

I use this trick into my tests (for other modules), but combining fork and daemons with stdout capturing is not really a good idea. Actually, the unit test jumps to the ensure of the method if I do it.

Thanks!
--Miguel.

Detatch doesn't consider external logging

We're noticing with the daemons gem that when it detaches the process for daemonization, it closes all the file descriptors and I/O streams. On the surface that's fine, but when it re-opens them, it doesn't consider external I/O streams and only opens the STD* pipes and logging to files. It seems like there's an assumption that the only logging that would take place is internal via one of the STDs or to a file. An example would be using the papertrail/remote_syslog_loger gem and witnessing the stream cut off (RemoteSyslogLogger::UdpSender error: IOError: closed stream).

If I'm way off here or there's a workaround for this, let me know. We see this the most in relation to the use of the delayed_job gem, which uses daemons.

When daemon is not running, status subcommand exit in non-zero status

I'd like to have Daemons return non-zero value when I try status subcommand for a not-working daemon.
Right now, the status subcommand always exit by the status '0'.
Normally, the status subcommand would exit by the status '3' when the daemon is not running. I hope Daemons be the same.

As far as I see the source code, it may require not-so-small change, so I created this issue on "Feature Request".

Ruby Daemons: Can monitor + multiple keep several worker children up?

We are using daemons via active_messaging to keep our background
pollers (message queue consumers) running. We now need to increase the
amount of work done, and are looking into the multiple option. How can
we keep 4 (or any consistent number) of workers up and running. We
typically monitor the pid file with monit and have it call 'start' if
the process dies, but with multiple there is no way to tie the process
that is running to a specific pid file. Rephrased: If worker 3 dies,
and monit calls start again because poller2.pid is empty, the multiple
option just cases poller4.pid to be created. Monit then doesn't see a
process for poller2.pid and calls start again ad infinitum.

We also experimented with the 'monitor' option, but it only keeps one
worker running at all times. Calling start 4 times does spawn 4
workers and the monitor worker, but when I kill any of the workers
monitor doesn't restart it (how could it know about them it only knows
about the first worker created in the first start call right?).

getting error while accessing some external file

I have created a file called my_server.rb and my_server_crl.rb

in my_server.rb I have following code
require './src/abcd.rb'

loop do
p "@@@@@@@@ Welcome to Daemon world @@@@@@@@@@@@@"
a = ABCD.new
a.get_status()
sleep(5)
end

Here When I am trying to require some external file I am getting error.

Sequel postgres connection fails when server run as daemon

Not sure if this is the right repo to post this issue to, so feel free to remove it.

I've been using Sequel gem (http://sequel.jeremyevans.net/) with postgres adapter inside Goliath, which in turn uses daemons gem and I've noticed a very weird behavior.

If Goliath is run as a daemon, it fails with the following error:

Sequel::DatabaseDisconnectError: PG::ConnectionBad: PQconsumeInput() SSL connection has been closed unexpectedly

whereas if it is run normally, this never happens.

This error also doesn't happen with sqlite, both in normal and daemonized modes.
Any hints as to why this might be happening?

Add ability to specify log file name, not just the directory

Specifying log_output: true and log_dir in the options allows us to specify where the output file should go, but it always is of format app_name + '.output'. We have a log file parser that expects a different format and it would be great if there was a log_filename option or similar.

Question: Semantic Versioning

Hi,

does this gem follow Semantic Versioning?

In other words, is it safe to set spec.add_dependency 'daemons', '~> 1.3' without incurring in breaking changes?

Thanks

Using daemons to as described in section 3 of Basic Usage is broken since 70f69a71ce1f1e19e254203d6b8bcff5abc3796c

The problem is that the @pid.pid in Deamons::Application is not getting updated when Daemonize.call_as_deamon is run because it is being set in the child process. You can see the problem by running the call examples (they run but leave processes running since Daemons.group.stop_all(true) wont find them without pids). This got broken by a commit which tried to avoid the race condition that happens when a parent process and child process try to update the same variable, but that would only happen if call_as_deamon ran a thread instead of a fork. Fortunately the function already handles interprocess communication using IO pipes, so we just need to revert the commit's changes to daemons/lib/daemons/application.rb to fix this.

QUESTION: checking exit status of process

Ok, so, I'm trying to run a daemon like so:

Daemons.run_proc("some_process.rb") do
   raise "I FAILED" 
end

when I do:

ruby some_process.rb start
echo $?

the echo returns a success 0 code instead of 1.
I've also tried to explicitly do an exit 1, but still, the return code is 0.

What is the correct way to do error checking?
Thanks!

Problematic behavior when handling TERM Signal

Problem

It toke me quite a while to figure out why I was seeing errors like this in my logs:

I, [2021-11-02T20:58:33.944764 #131302]  INFO -- : *** below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally ***                                   
E, [2021-11-02T20:58:33.944878 #131302] ERROR -- : Value will be available once the pipeline executes. (Redis::FutureNotReady)                                                                                                                
                                                                                                                                                                                                                                              
I, [2021-11-02T20:58:33.944946 #131302]  INFO -- : *** below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***     
E, [2021-11-02T20:58:33.945208 #131302] ERROR -- : stream closed in another thread (IOError)                                                                                                                                                  
                                                                                                                                                                                                                                              
E, [2021-11-02T20:58:33.945298 #131302] ERROR -- : failed to allocate memory (NoMemoryError)                                                                                                                                                  
                                                                                                                                                                                                                                              
E, [2021-11-02T20:58:33.945372 #131302] ERROR -- : stack level too deep (SystemStackError)                                                                                                                                                    
                                                                                                                                                                                                                                              
E, [2021-11-02T20:58:33.945582 #131302] ERROR -- : machine stack overflow in critical region (fatal)                                                                                                                                          
                                                                                                                                                                                                                                              
E, [2021-11-02T20:58:33.945641 #131302] ERROR -- : exception reentered (fatal)                                                                                                                                                                
                                                                                                                                                                                                                                              
E, [2021-11-02T20:58:33.951859 #131302] ERROR -- : Value will be available once the pipeline executes. (Redis::FutureNotReady)

After some testing I managed to get it to show up when I would use daemon-rails' gem rake daemons:<name>:restart

I managed to figure out the reason, and IMO it's a pitfall that I wouldn't be the only one to fall into.

daemons catches the TERM Signal internally to wrapup the work (:+1: ).
But Signal.trap (or Kernel.trap for that matter) work in such a way, that when you define a handler, you overwrite the handler that was previously defined (the method returns the previous handler, but you have to know & remember about it).
So to ovewrite daemons' intermal TERM handling it's a matter of simple:

Signal.trap('TERM') do
  $running = false
end

I've seen this done or suggested. (and I was doing this myself).

Then daemons creates these logs as in if options[:backtrace] && !options[:ontop] && !$daemons_sigterm - it depends on $daemons_sigterm to be set. Meaning if daemons didn't receive a TERM signal, and it's stopping, it thinks it's a termination due to failure, and tries to figure out what went wrong.

BUT doing a daemons-rails :restart or even, daemons' Application.stop calls/sends TERM - and so causes these ERRORs in the logs if you happen to trap the TERM signal.

Solution

For me the "passing" the Signal with this approach helped.

daemons handles it internally - providing an option, but I only learned about this when digging through the code.

So long story short - what do you think about mentioning this issue with Signal in Readme or documentation ? ๐Ÿค”
Or even mention the options[:stop_proc] in readme or documentation ๐Ÿค” (I couldn't find mention of it :( )
I mean I could write something, but I'm interested in another opinion :)

PidFile lookup does not work with processes named process.1, process.10, and so on

I ran into this issue while using Delayed::Job -- maybe this is actually a bug Delayed::Job should fix, however, I believe this is still somewhat broken in Daemons.

Here's the bug:

File lib/daemons/pidfile.rb, line 36

36: def PidFile.find_files(dir, progname, delete = false)
37: files = Dir[File.join(dir, "#{progname}*.pid")]
38:
39: files.delete_if {|f| not (File.file?(f) and File.readable?(f))}
40: if delete
41: files.delete_if do |f|
42: pid = File.open(f) {|h| h.read}.to_i
43: rsl = ! Pid.running?(pid)
44: if rsl
45: puts "pid-file for killed process #{pid} found (#{f}), deleting."
46: begin; File.unlink(f); rescue ::Exception; end
47: end
48: rsl
49: end
50: end
51:
52: return files
53: end

On line 37, the PidFile class will match any string that is the same as the program name (say, delayed_job.10 would match a check for delayed_job.1). This will also match any similar PIDs.

This appears to come about from the way Daemons expects to number PID files (#{progname}#{number}.pid). Admittedly a corner case, but could the naming scheme be changed to avoid such conflicts?

Thanks for this report.

So I assume, a naming scheme like #{progname}_no#{number}.pid would fix your issue? Or do you have any other suggestion?

Specify number of processes

I'm trying to build a daemon that accepts the number of processes to spawn as an argument.

Here's the runner:


#!/usr/bin/env ruby

require 'daemons'

Daemons.run(
  './script/startup/jobs',
  dir_mode: :normal,
  dir: '/var/app/support/pids',
  log_dir: '/var/app/support/logs/',
  logfilename: 'async_runner.log',
  backtrace: '/var/app/support/logs/async_runner.error.log',
  multiple: true,
  monitor: true,
  monitor_interval: 180 # seconds
)

And this is script/startup/jobs:

#!/usr/bin/env ruby

require 'optparse'
require 'ostruct'
require File.expand_path('../../../config/environment',  __FILE__)

lib_path = Dir["#{Rails.root}/lib/async/*.rb", "#{Rails.root}/lib/*.rb"]
lib_path.each { |f| require f }

options = OpenStruct.new(worker_count: ENV['ASYNC_SUBSCRIBER_COUNT'].to_i || 1)

opts = OptionParser.new do |opts|
  opts.banner = 'Usage: jobs [options]'
  opts.separator ''
  opts.on('-n', '--worker_count count', 'Number of worker process to spawn') do |count|
    options.worker_count = count.to_i
  end
  opts.on('-c', '--task_classes classes', 'classes to run') do |classes|
    options.task_classes = classes
  end
end

opts.parse!

runner = AsyncRunner.new({
  task_classes: options.task_classes
})

options.worker_count.times do |x|
  Rails.logger.info "Starting async runner daemon...."
  runner.run
end

This is not working. It ends up running runner.run only once.

I also tried wrapping runner.run inside a fork but that is not working either. Any ideas on how to do this?

Thanks.

Failure to install development dependency pry-byebug with '~> 0' version constrain

$ gem depend daemons -v 1.2.4 
Gem daemons-1.2.4
  pry-byebug (~> 0, development)
  rake (~> 0, development)
  rspec (~> 3.1, development)
  simplecov (~> 0, development)

But it is impossible to install pry-byebug

$ gem install pry-byebug --clear-source --source=https://rubygems.org -v '~> 0'
ERROR:  Could not find a valid gem 'pry-byebug' (~> 0) in any repository
ERROR:  Possible alternatives: pry-byebug
$ gem install pry-byebug --clear-source --source=https://rubygems.org -v '~> 0' --prerelease
ERROR:  Could not find a valid gem 'pry-byebug' (~> 0) in any repository
ERROR:  Possible alternatives: pry-byebug

Where is the documentation?

This is no link to the documentation that I can see. Rubygems links to this repo for documentation. I need to know all of the options available to the module. Where is the full documentation?

How to set log_dir as relative path

Hi,

I have a daemon which exists in a rails app so I'm wanting the configure daemons to put the pid and log files in the normal rails directories.

I have this setup:

options = {
  app_name: 'test',
  monitor: true,
  dir: '../tmp/pids/',
  log_output: true,
  backtrace: true,
  log_dir: '../log/',
  output_logfilename: "test.log",
}

Daemons.run('test.rb', options)

This creates the pid files in RAILS_ROOT/tmp/pids but doesn't create a log file.

I tried removing the log_dir setting, which creates the file in RAILS_ROOT/tmp/pids.

I tried setting log_dir: '../../log/', thinking that log_dir could be relative to the dir setting. No log file is created. I assume that log_dir is relative to somewhere, but I don't know how.

I tried setting log_dir: '/tmp/', to an absolute path and that works fine.

I have a look at the code:

def logdir
  logdir = options[:log_dir]
  unless logdir
    logdir = options[:dir_mode] == :system ? '/var/log' : pidfile_dir
  end
  logdir
end

def output_logfilename
  filename = options[:output_logfilename]
  unless filename
    filename = @group.app_name + '.output'
  end
  filename
end

def output_logfile
  (options[:log_output] && logdir) ? File.join(logdir, output_logfilename) : nil
end

def logfilename
  filename = options[:logfilename]
  unless filename
    filename = @group.app_name + '.log'
  end
  filename
end

def logfile
  logdir ? File.join(logdir, logfilename) : nil
end

I see that it's doing File.join(logdir, output_logfilename) but where is that relative to?

So my question is how can I have the pid files to tmp/pids and log file to log/? Am I missing something simple?

This gems is great, thanks for putting your time into it.

Thanks,
Dave

Spurious Bad File Descriptor warnings

I end up with a ton of these in my log files:

ERROR -- : Bad file descriptor (Errno::EBADF)
gems/daemons-1.1.9/lib/daemons/daemonize.rb:137:in `for_fd'
gems/daemons-1.1.9/lib/daemons/daemonize.rb:137:in `block in close_io'
gems/daemons-1.1.9/lib/daemons/daemonize.rb:137:in `initialize'
gems/daemons-1.1.9/lib/daemons/daemonize.rb:137:in `new'
gems/daemons-1.1.9/lib/daemons/daemonize.rb:137:in `close_io'
gems/daemons-1.1.9/lib/daemons/daemonize.rb:75:in `call_as_daemon'
gems/daemons-1.1.9/lib/daemons/application.rb:259:in `start_proc'
gems/daemons-1.1.9/lib/daemons/application.rb:296:in `start'
gems/daemons-1.1.9/lib/daemons/controller.rb:70:in `run'

Looks like the close-all-file-handles loop isn't able to silence its warnings and my logger is capturing them. That loop normally operates on a lot of nonexistent file handles, so keeping it quiet is important :)

apps inherit app_name even when new name is specified

I'm trying to run multiple groups of daemons, each group with a different name. The daemons run correctly, but they inherit their name from the first group to run even when I explicitly specify a new name.

example code:

options1 = {
  multiple: true,
  app_name: task1
}
options2 = {
  multiple: true,
  app_name: task2
}
2.times do Daemons.call(options1) { doTask1() } end
2.times do Daemons.call(options2) { doTask2() } end

The above code correctly spawns the four tasks but incorrectly refers to all four by the name task1.

Looking at the source code, I believe the issue is here in Application.new where new applications inherit the name of their group.

Is there a better way to use Daemons such these tasks are created within different groups? (Is this intended behavior?) Or is this a bug?

Closing of all FD's breaks existing logging and connections

I'm debugging a problem some customers of ours are running into. Our monitoring gem has some file descriptors open, but these are closed after a daemonize call:

3.upto(8192) do |i|
  IO.for_fd(i).close rescue nil
end

This happens in

3.upto(8192) do |i|

From my point of view it is actually essential that these FD's stay open after the daemonize. Could you explain why this behaviour is present here? Would you be open to removing it?

Stopped daemon processes keep respawning

I've been using daemons for a year or two but have recently upgraded to the latest version (1.2.3).

Within a few days of doing this I've hit the following problem.
I run multiple processes (30+) via a daemon wrapper script (extract follows).

(1..job_count).each do |i|
  Daemons.run_proc(
    "tweet-processor-worker-#{Rails.env}-#{"%03d" % i}",
    :dir_mode => :normal,
    :dir => File.join(pwd, "../tmp/pids"),
    :backtrace => true,
    :monitor => true,
    :log_output => true
  ) do
    exec "bundle exec backburner -q tweet-process -r #{app_path}"
  end
end

However, after stopping all processes (by passing stop to the script above) a few of the processes are still alive.
I eventually realised that the process was stopping then respawning.
The output logs contain variations on the following...

["tweet-process"]
log writing failed. execution expired
log writing failed. execution expired
log writing failed. can't be called from trap context
Starting backburner service...

It then restarts.
I've tried killing the processes (with and without -9) and they keep coming back.
I really want to avoid having to reboot the server to get rid of them.

Any suggestions as to how I can stop them respawning?

Ruby Daemons Library with the Daemons.Run function

Hello Thomas,

I've been developing a back-end server system in ruby and I was using your awesome Daemonization library seen at http://daemons.rubyforge.org/. One of the issues I am hitting is that when I execute the Daemons.run(script) method the process launches and is daemonized but the rest of the script stops running. For a full example please see: http://pastebin.com/PAwKX6RN

This seems like it might be a limitation of forking in Ruby but if I am utilizing your library incorrectly or you have any insight on how I could get my desired end result I appreciate any input.

Thanks,
Michael Brune

Make working directory compatible with macOS Catalina

Hello!
I noticed that this gem uses '/' as its working directory here: [lib/daemons/daemonize.rb#L108].
In macOS Catalina this is a read-only directory, which causes issues.
My understanding of the change in macOS Catalina is that it by default partitions the file system into read-only for the OS, and read-write for applications.

I hate to make a gem OS-specific, but maybe some kind of extra configuration might be possible?

Stopping daemon via wrapper script can kill unrelated processes

In v1.2.2 and earlier (at least to 1.1.9), calling 'ruby mydaemon_control.rb stop' can kill one of the invoking user's other processes if the pidfile contains the pid of one of those processes. I was surprised by this when, after trying to stop a daemon that wasn't running, my IDE spontaneously closed.

The issue seems to be that the process is just sent a stop signal without checking to see if it's actually the daemon process we want to stop. (Pidfile cleanup works normally for me, but I don't bother to stop any running daemons before I shut down my dev box, so I tend to get stale pidfiles.) I've solved similar issues in the past by checking the process name (if the process is running) before taking any action on it.

OSX hangs on close_io

I'm using delayed_job which utilizes daemons. When I run "delayed_job run" from my application, its hanging in this block on my OSX box (but seems ok in my docker container on Ubuntu)..

  def close_io
    # Make sure all input/output streams are closed
    # Part I: close all IO objects (except for $stdin/$stdout/$stderr)
    ObjectSpace.each_object(IO) do |io|
      unless [$stdin, $stdout, $stderr].include?(io)
        io.close rescue nil
      end
    end

If I add a print in the loop here, I get this:

jack:import_tester sblackstone$ ./bin/delayed_job run
#<File:/Users/sblackstone/.rvm/gems/ruby-2.3.1/gems/actioncable-5.0.0.1/lib/action_cable/channel.rb (closed)>
#<File:/Users/sblackstone/code/import_tester/config/secrets.yml (closed)>
#<File:/Users/sblackstone/code/import_tester/log/development.log>
#<IO:fd 32>

which from the output of lsof is some sort of pipe.

If I change the order of the functions in close_io so that it runs the close_fd loop before the "io.close" loop, it manages to get going (albeit other things seem to break like logging)

If this isn't a daemons issue, I'm happy to open something with the delayed_job folks - Thanks..

I'm using OSX El Cap..

Unable to find 1.2.0

Firstly, thank you for the release of the new version.

However, I only appear to be able to use it with Ruby 2.1.0. With any other version I have tried (2.2.0, 2.2.1 and 1.9.3) I get:

$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching version metadata from https://rubygems.org/..
Could not find daemons-1.2.0 in any of the sources

and

$ gem install daemons -v "1.2.0"
ERROR:  Could not find a valid gem 'daemons' (= 1.2.0) in any repository

I have no problem at all using it with version 2.1.0. Very odd. I don't see anything, either in Github or on Ruby Gems, that specifies the version of Ruby. Does anyone else see this?

`daemons` always exits with zero

even when something causes an error, the application exits with zero.

def catch_exceptions(&block)
begin
block.call
rescue CmdException, OptionParser::ParseError => e
puts "ERROR: #{e}"
puts
print_usage
rescue RuntimeException => e
puts "ERROR: #{e}"
end
end

call_as_daemon method don't stop child process

Your environment

  • ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
  • daemons (1.4.1)

Describe the bug

Calling Process.waitpid inside the at_exit method will prevent the child process from stopping.

To Reproduce

Script:

Gemfile

# frozen_string_literal: true

source "https://rubygems.org"

gem "daemons"

test_daemon.rb

#!/usr/bin/env ruby

require 'bundler/setup'
Bundler.setup
require 'daemons'

at_exit do
  begin
    Process.waitpid
  rescue Errno::ESRCH, Errno::ECHILD
  end
end

2.times do |i|
  Daemons.run_proc("test_daemon.#{i}") do
    loop do
    end
  end
end

Terminal:

$ test_daemon.rb start

Child process doesn't stop.

$ ps aux
--snip--
sada     14719  1.8  0.2 177232 37168 pts/6    Sl+  17:01   0:00 ruby ./test_daemon.rb start
sada     14735  0.0  0.2 177232 33832 ?        Ssl  17:01   0:00 ruby ./test_daemon.rb start
sada     14737 94.6  0.2 180308 37540 ?        Rl   17:01   0:08 test_daemon.0

The following fork operations are no longer possible.

  1. Forks another child process and exits first child. This prevents the potential of acquiring a controlling terminal.

daemons/lib/daemons.rb

Lines 43 to 51 in a0e84bc

# 1. Forks a child (and exits the parent process, if needed)
# 2. Becomes a session leader (which detaches the program from
# the controlling terminal).
# 3. Forks another child process and exits first child. This prevents
# the potential of acquiring a controlling terminal.
# 4. Changes the current working directory to "/".
# 5. Clears the file creation mask (sets +umask+ to 0000).
# 6. Closes file descriptors (reopens +$stdout+ and +$stderr+ to point to a logfile if
# possible).

By the way, I encountered this problem when using delayed_job and debug.

Expected behavior

Child processes can be stopped.
Since the first child process should be stopped, I thought it would be a good idea to change the call to the exit! method.

exit if pid = safefork

Test Coverage?

I'm not noticing any RSpec or MiniTest coverage for the gem. Is that by design or is there another mechanism? I'm planning to fork it and add assurances (tests) for a project that requires a certain level of coverage to be in place.

If there is not coverage in place, is coverage desired? and if so, is there a preference (RSpec or MiniTest)?

Windows: fork() function is unimplemented on this machine (NotImplementedError)

Hello, I'm using ruby on windows, but daemons won't work because fork() is unimplemented on windows.
Is there a workaround for this?
Thanks.

D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/daemonize.rb:10:in `fork': fork() function is unimplemented on this machine (NotImplementedError)
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/daemonize.rb:10:in `safefork'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/daemonize.rb:45:in `call_as_daemon'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/application.rb:270:in `start_proc'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/application.rb:296:in `start'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/controller.rb:56:in `run'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons.rb:197:in `block in run_proc'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons/cmdline.rb:92:in `catch_exceptions'
        from D:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/daemons-1.2.4/lib/daemons.rb:196:in `run_proc'
        from DynDNS.rb:15:in `<main>'

Stopping daemon log file error?

When I am trying to stop I get this message written:
Config:

Daemons.run(
  MYD_PATH,
  app_name: 'my_daemon',
  dir_mode:          :normal,
  dir:                TMP_PIDS_DIR,
  backtrace:          true,
  monitor:            true,
  log_output:         true,
  logfilename:        'daemon.log',
  output_logfilename: 'outputfile.txt',
  mode:               :load
)

SIGTERM
["/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:56:in sleep'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:56:in block in watch'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:43:in loop'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:43:in watch'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:67:in block in start_with_pidfile'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:62:in fork'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:62:in start_with_pidfile'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/monitor.rb:93:in start'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/application_group.rb:147:in create_monitor'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/application.rb:284:in start'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/controller.rb:56:in run'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons.rb:148:in block in run'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons/cmdline.rb:92:in catch_exceptions'", "/usr/local/lib/ruby/gems/2.3/gems/daemons-1.2.4/lib/daemons.rb:147:in run'", "/usr/local/lib/ruby/gems/2.3/gems/xxxxxx-0.1.14/bin/daemonctl23:10:in <top (required)>'", "/usr/local/bin/daemonctl23:23:in load'", "/usr/local/bin/daemonctl23:23:in `

'"]

stderr in case of no instances running

in /lib/daemons/controller.rb

there are lines that would output an information that no "daemon" instances is running using "puts" function.

But that will make no stderr returned when use the script on Linux service.

Could you please use the funtion "abort" instead of "puts" so this would be more useful.

Logrotate

I am having issues getting our daemon script to play nice with logrotate. Since logging is being managed by the daemon gem, I am wondering if it accepts a reopen log signal like USR1 or if there is a different preferred method? Thanks.

CPU 100% in version 1.2.1 update (previous version 1.1.9 works fine)

I have a pretty bland config ./bin/application.rb:

require 'rubygems'
require 'daemons'

pwd = File.dirname(File.expand_path(__FILE__))
file = pwd + '/app.rb'

options = {
  :app_name   => "application",
  :dir_mode   => :normal,
  :dir        => File.join(pwd, '../tmp/pids'),
  :multiple   => false,
  :backtrace  => true,
  :log_output => true,
  :log_dir    => File.join(pwd, '../log'),
  :monitor    => true,
  :ontop      => false,
}

Daemons.run('./bin/app.rb', options)

./bin/app.rb is a process that polls a queue.

When I run this: bundle exec ruby bin/application.rb start, the application_monitor process starts, then within seconds it starts consuming more and more CPU cycles (until the CPU has no more to give).

Additional problem is that the daemon doesn't respond properly to stop signals. It fails to die, won't take down the processes it spawned and it spawns a new process (essentially leaking them). I can spam it w/ stops and it will eventually terminate, leaving all the spawned processes for me to kill by hand.

Ruby Version 2.1.1
Daemon Version 1.2.1

For now I am just going to stick with version 1.1.9 but I thought I would report this in hopes of finding a resolution that allows me to stick w/ a newer version.

Monitored daemon with multiple=false improperly runs multiple times

Hi!

I've run into a bug that's unfortunately a big issue for us. Basically, we have a daemon running, and we only want one instance of the daemon to run at once, and we run with monitoring enabled so that it is restarted automatically on error conditions.

We're running it with a command like the following:
Daemons.run(SERVICE_PATH, app_name: SERVICE_NAME, multiple: false, mode: :exec, monitor: true, log_output: true, dir: LOG_DIR, dir_mode: :normal, force_kill_waittime: 15, )

We end up in a state occasionally where we will end up with multiple instances of our service running at once, as well as multiple instances of the associated monitors.

I've narrowed this down to occurring when you delete the pid files for the service at the same time that you delete the pid file for the monitor, and then start the service again via the command line. Even though the files have been deleted, the monitor and service continues running as before.

Starting the service again via the command line creates a new monitor, which starts a new service, and we end up with a state with multiple monitors and multiple services running at the same time.

This could potentially be fixed by having the monitor watch occasionally to ensure that it's pid file still exists, and if it doesn't it could shut everything down. Another alternative could be to have the startup logic look for the process name in addition to the pid file in an attempt to catch this case.

Any thoughts? I'm happy to answer any questions!

PidFile.find_files glob is too loose

If you have a program name that is a prefix of another you cannot run it.

I have a progname = 'doppio_preview_2', which prevents me from starting my program called 'doppio_preview' because the glob find the pid.

I have patched this in a fork but I am unsure how to pass this back to the project.

loe@c6a1510

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.