Class: Forever::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/forever/base.rb,
lib/forever/base.rb

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &block) ⇒ Base

Returns a new instance of Base.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/forever/base.rb', line 5

def initialize(options={}, &block)
  options.each { |k,v| send(k, v) }

  instance_eval(&block)

  Dir.chdir(dir) if exists?(dir)
  Dir.mkdir(File.dirname(log)) if log && !File.exist?(File.dirname(log))
  Dir.mkdir(File.dirname(pid)) if pid && !File.exist?(File.dirname(pid))

  stop!

  return if ARGV[0] == "stop" || on_ready.nil?

  fork do
    $0 = "Forever: #{$0}"
    puts "=> Process demonized with pid #{Process.pid}"

    %w(INT TERM KILL).each { |signal| trap(signal)  { stop! } }

    File.open(pid, "w") { |f| f.write(Process.pid.to_s) } if pid

    stream      = log ? File.new(log, "w") : File.open('/dev/null', 'w')
    stream.sync = true

    STDOUT.reopen(stream)
    STDERR.reopen(STDOUT)

    begin
      on_ready.call
    rescue Exception => e
      Thread.list.reject { |t| t==Thread.current }.map(&:kill)
      on_error[e] if on_error
      stream.print "\n\n%s\n  %s\n\n" % [e.message, e.backtrace.join("\n  ")]
      sleep 30
      retry
    end
  end
end

Instance Method Details

#configObject Also known as: to_yaml



116
117
118
# File 'lib/forever/base.rb', line 116

def config
  { :dir => dir, :file => file, :log => log, :pid => pid }.to_yaml
end

#dir(value = nil) ⇒ Object

Base working Directory



54
55
56
# File 'lib/forever/base.rb', line 54

def dir(value=nil)
  value ? @_dir = value : @_dir
end

#file(value = nil) ⇒ Object

Caller file



47
48
49
# File 'lib/forever/base.rb', line 47

def file(value=nil)
  value ? @_file = value : @_file
end

#log(value = nil) ⇒ Object

File were we redirect STOUT and STDERR, can be false.

Default: dir + ‘log/.log’



63
64
65
66
# File 'lib/forever/base.rb', line 63

def log(value=nil)
  @_log ||= File.join(dir, "log/#{File.basename(file)}.log") if exists?(dir, file)
  value ? @_log = value : @_log
end

#on_error(&block) ⇒ Object

Callback raised when an error occour



100
101
102
# File 'lib/forever/base.rb', line 100

def on_error(&block)
  block_given? ? @_on_error = block : @_on_error
end

#on_ready(&block) ⇒ Object

Callback to fire when the daemon start



107
108
109
# File 'lib/forever/base.rb', line 107

def on_ready(&block)
  block_given? ? @_on_error = block : @_on_error
end

#pid(value = nil) ⇒ Object

File were we store pid

Default: dir + ‘tmp/.pid’



73
74
75
76
# File 'lib/forever/base.rb', line 73

def pid(value=nil)
  @_pid ||= File.join(dir, "tmp/#{File.basename(file)}.pid") if exists?(dir, file)
  value ? @_pid = value : @_pid
end

#stop!(kill = true) ⇒ Object

Search if there is a running process and stop it



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/forever/base.rb', line 81

def stop!(kill=true)
  if exists?(pid)
    _pid = File.read(pid).to_i
    puts "=> Found pid #{_pid}..."
    FileUtils.rm_f(pid)
    begin
      puts "=> Killing process #{_pid}..."
      Process.kill(:KILL, _pid)
    rescue Errno::ESRCH => e
      puts "=> #{e.message}"
    end
  else
    puts "=> Pid not found, process seems don't exist!"
  end
end

#to_sObject Also known as: inspect



111
112
113
# File 'lib/forever/base.rb', line 111

def to_s
  "#<Forever dir:#{dir}, file:#{file}, log:#{log}, pid:#{pid}>"
end