26

I want to write a Ruby program that will always be running in the background (a daemon) on my Mac.

Can someone point me in the right direction on how this would be done?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
ab217
  • 16,900
  • 25
  • 74
  • 92

5 Answers5

28

Ruby 1.9.x has now the following:

Process.daemon

Put it in your code and that's it.

Taken from "Daemon Processes in Ruby."

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Hertzel Guinness
  • 5,912
  • 3
  • 38
  • 43
18

Use Daemonize.rb

require 'daemons'
Daemons.daemonize

Very simple sample: http://github.com/utkarsh2012/backitup/blob/master/backitup.rb

How to install daemons gem:

gem install daemons
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
zengr
  • 38,346
  • 37
  • 130
  • 192
  • This might be a stupid question, but where is the daemonize.rb file? Is it a gem, is there a place on the web where I can find it, is it the standard library, or what? – ab217 Sep 10 '10 at 23:05
  • It's a gem. You just install and start using it. – zengr Sep 10 '10 at 23:13
  • 2
    and if the app is closed will the Daemon still run ? – lesce Feb 07 '12 at 12:58
4

Ah, Google to the rescue! Check out

http://fitzgeraldsteele.wordpress.com/2009/05/04/launchd-example-start-web-server-at-boot-time/

wherein a helpful blogger provides an example of writing a launchd plist to launch a ruby Web application server.

Kaelin Colclasure
  • 3,925
  • 1
  • 26
  • 36
  • Glad you thought it was helpful! I've personally come to like launchd...for one it can restart your process if it dies unexpectedly. – fitzgeraldsteele Oct 25 '10 at 21:13
3

Need to see the daemons-rails gem for Rails 3 (based on rails_generator):

https://github.com/mirasrael/daemons-rails

Possible to generate daemon stub like this:

rails generate daemon <name>

Features:

  • individual control script per daemon
  • rake:daemon command per daemon
  • capistrano friendly
  • app-wide control script
  • monitoring API
  • possible multiple daemon sets
oklas
  • 7,935
  • 2
  • 26
  • 42
3

This is a module to daemonize your code. Here's an offshoot that wraps an existing script.

Essentially it boils down to this (from Travis Whitton's Daemonize.rb, the first link above, modified for some program I wrote ages ago):

private
# This method causes the current running process to become a daemon
# If closefd is true, all existing file descriptors are closed
def daemonize(pathStdErr, oldmode=0, closefd=false)
    srand # Split rand streams between spawning and daemonized process
    safefork and exit# Fork and exit from the parent

    # Detach from the controlling terminal
    unless sess_id = Process.setsid
        raise 'Cannot detach from controlled terminal'
    end

    # Prevent the possibility of acquiring a controlling terminal
    if oldmode.zero?
        trap 'SIGHUP', 'IGNORE'
        exit if pid = safefork
    end

    Dir.chdir "/"   # Release old working directory
    File.umask 0000 # Insure sensible umask

    if closefd
        # Make sure all file descriptors are closed
        ObjectSpace.each_object(IO) do |io|
            unless [STDIN, STDOUT, STDERR].include?(io)
                io.close rescue nil
            end
        end
    end

    STDIN.reopen "/dev/null"       # Free file descriptors and
    STDOUT.reopen "/dev/null"   # point them somewhere sensible
    STDERR.reopen pathStdErr, "w"           # STDOUT/STDERR should go to a logfile
    return oldmode ? sess_id : 0   # Return value is mostly irrelevant
end

# Try to fork if at all possible retrying every 5 sec if the
# maximum process limit for the system has been reached
def safefork
    tryagain = true
    while tryagain
        tryagain = false
        begin
            if pid = fork
                return pid
            end
        rescue Errno::EWOULDBLOCK
            sleep 5
            tryagain = true
        end
    end
end
Mark
  • 106,305
  • 20
  • 172
  • 230
  • Mark, while this is the right code for more vanilla Unix systems, and it will more-or-less work on Mac OS X, it's really not the right recipe... I don't have a canned recipe handy for registering a ruby script with launchd, but that's what the OP probably should be looking for. :-) – Kaelin Colclasure Sep 10 '10 at 21:52
  • @Kaelin, excellent point. I should have read the question more carefully. Unfortunately, I don't no nothing about no Macs... – Mark Sep 10 '10 at 21:57
  • great explaination. – z atef Oct 06 '16 at 01:29