Module: Daemoned::ClassMethods

Defined in:
lib/sweatshop/daemoned.rb

Instance Method Summary collapse

Instance Method Details

#after(&block) ⇒ Object



111
112
113
# File 'lib/sweatshop/daemoned.rb', line 111

def after(&block)
  callbacks[:after] = block
end

#arg(*args, &block) ⇒ Object



83
84
85
# File 'lib/sweatshop/daemoned.rb', line 83

def arg(*args, &block)
  self.extra_args << [args, block]
end

#before(&block) ⇒ Object



107
108
109
# File 'lib/sweatshop/daemoned.rb', line 107

def before(&block)
  callbacks[:before] = block
end

#callback!(callback) ⇒ Object



129
130
131
# File 'lib/sweatshop/daemoned.rb', line 129

def callback!(callback)
  callbacks[callback].call if callbacks[callback]
end

#callbacksObject



91
92
93
# File 'lib/sweatshop/daemoned.rb', line 91

def callbacks
  @callbacks ||= {}
end

#config {|@@config| ... } ⇒ Object

Yields:



103
104
105
# File 'lib/sweatshop/daemoned.rb', line 103

def config
  yield @@config
end

#daemonize(opts = {}, &block) ⇒ Object

options may include:

:loop_every Fixnum (DEFAULT 0)

How many seconds to sleep between calls to your block

:timeout Fixnum (DEFAULT 0)

Timeout in if block does not execute withing passed number of seconds

:kill_timeout Fixnum (DEFAULT 120)

Wait number of seconds before using kill -9 on daemon

:die_on_timeout BOOL (DEFAULT False)

Should the daemon continue running if a block times out, or just run the block again

:ontop BOOL (DEFAULT False)

Do not daemonize.  Run in current process

:before BLOCK

Run this block after daemonizing but before begining the daemonize loop.
You can also define the before block by putting a before do/end block in your class.

:after BLOCK

Run this block before program exists.  
You can also define the after block by putting an after do/end block in your class.

:die_if BLOCK

Run this check after each iteration of the loop.   If the block returns true, throw a DieTime exception and exit
You can also define the after block by putting an die_if do/end block in your class.

:exit_if BLOCK

Run this check after each iteration of the loop.   If the block returns true, exit gracefully
You can also define the after block by putting an exit_if do/end block in your class.

:log_prefix BOOL (DEFAULT true)

Prefix log file entries with PID and timestamp


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/sweatshop/daemoned.rb', line 168

def daemonize(opts={}, &block)
  self.options = opts
  parse_options
  return unless ok_to_start?

  puts "Starting #{script_name}..."
  puts "Logging to: #{log_file}" unless ontop?
  
  unless ontop?
    safefork do
      open(pid_file, 'w'){|f| f << Process.pid }
      at_exit { remove_pid! }

      trap('TERM') { callback!(:sig_term)                            }
      trap('INT')  { callback!(:sig_int)  ; Process.kill('TERM', $$) }
      trap('HUP')  { callback!(:sig_hup)                             }

      sess_id = Process.setsid
      reopen_filehandes

      begin
        at_exit { callback!(:after) }
        callback!(:before)
        run_block(&block)
      rescue SystemExit
      rescue Exception => e
        $stdout.puts "Something bad happened #{e.inspect} #{e.backtrace.join("\n")}"
      end            
    end
  else
    begin
      callback!(:before)
      run_block(&block)
    rescue SystemExit, Interrupt
      callback!(:after)
    end
  end
end

#die_if(method = nil, &block) ⇒ Object



121
122
123
# File 'lib/sweatshop/daemoned.rb', line 121

def die_if(method=nil,&block)
  options[:die_if] = method || block
end

#exit_if(method = nil, &block) ⇒ Object



125
126
127
# File 'lib/sweatshop/daemoned.rb', line 125

def exit_if(method=nil,&block)
  options[:exit_if] = method || block
end

#extra_argsObject



87
88
89
# File 'lib/sweatshop/daemoned.rb', line 87

def extra_args
  @extra_args ||= [] 
end

#initialize_optionsObject



29
30
31
32
33
# File 'lib/sweatshop/daemoned.rb', line 29

def initialize_options    
  @@config             = Config.new
  @@config.script_path = File.expand_path(File.dirname($0))
  $0                   = script_name
end

#optionsObject



95
96
97
# File 'lib/sweatshop/daemoned.rb', line 95

def options
  @options ||= {}
end

#options=(options) ⇒ Object



99
100
101
# File 'lib/sweatshop/daemoned.rb', line 99

def options=(options)
  @options = options
end

#parse_optionsObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sweatshop/daemoned.rb', line 35

def parse_options
  opts = OptionParser.new do |opt|
    opt.banner = "Usage: #{script_name} [options] [start|stop]"

    opt.on_tail('-h', '--help', 'Show this message') do
      puts opt
      exit(1)
    end

    opt.on('--loop-every=SECONDS', 'How long to sleep between each loop') do |value|
      options[:loop_every] = value 
    end

    opt.on('-t', '--ontop', 'Stay on top (does not daemonize)') do
      options[:ontop] = true
    end

    opt.on('--log-file=LOGFILE', 'Logfile to log to') do |value|
      options[:log_file] = File.expand_path(value)
    end

    opt.on('--pid-file=PIDFILE', 'Location of pidfile') do |value|
      options[:pid_file] = File.expand_path(value)
    end

    opt.on('--no-log-prefix', 'Do not prefix PID and date/time in log file.') do
      options[:log_prefix] = false
    end
  end
  
  extra_args.each do |arg|
    opts.on(*arg.first) do |value|
      arg.last.call(value) if arg.last
    end
  end

  opts.parse!
  
  if ARGV.include?('stop')                                                         
    stop
  elsif ARGV.include?('reload')
    kill('HUP')
    exit
  elsif not ARGV.include?('start') and not ontop?
    puts opts.help
  end
end

#sig(*signals, &block) ⇒ Object



115
116
117
118
119
# File 'lib/sweatshop/daemoned.rb', line 115

def sig(*signals, &block)
  signals.each do |s|
    callbacks["sig_#{s}".to_sym] = block
  end
end