Class: Harbor::Daemon

Inherits:
Object
  • Object
show all
Defined in:
lib/harbor/daemon.rb

Constant Summary collapse

START_CONTEXT =
{
  :argv => ARGV.map { |arg| arg.dup },
  :cwd => `/bin/sh -c pwd`.chomp("\n"),
  :cmd => $0.dup
}
DEFAULT_SLEEP_SECONDS =
60

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(worker, log_file, seconds_between_runs = DEFAULT_SLEEP_SECONDS) ⇒ Daemon

Returns a new instance of Daemon.



16
17
18
19
20
21
22
23
24
25
# File 'lib/harbor/daemon.rb', line 16

def initialize(worker, log_file, seconds_between_runs = DEFAULT_SLEEP_SECONDS)
  @worker = worker

  # The template may include the tag %PID to be replaced with
  # the PID of the forked worker process.  Don't use @log_file
  # directly, use self.log_file
  @log_file_template = log_file
  
  @seconds_between_runs = seconds_between_runs
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



13
14
15
# File 'lib/harbor/daemon.rb', line 13

def logger
  @logger
end

#optionsObject (readonly)

Returns the value of attribute options.



14
15
16
# File 'lib/harbor/daemon.rb', line 14

def options
  @options
end

#workerObject (readonly)

Returns the value of attribute worker.



14
15
16
# File 'lib/harbor/daemon.rb', line 14

def worker
  @worker
end

Instance Method Details

#cleanup!Object



88
89
90
# File 'lib/harbor/daemon.rb', line 88

def cleanup!
  worker.cleanup! if worker.respond_to?(:cleanup!)
end

#detachObject



31
32
33
34
35
36
37
38
39
40
# File 'lib/harbor/daemon.rb', line 31

def detach
  srand
  fork and exit
  Process.setsid # detach -- we want to be able to close our shell!

  log_directory = ::File.dirname(self.log_file)
  ::File.mkdir_p(log_directory) unless ::File.directory?(log_directory)

  redirect_io(@log_file)
end

#log_fileObject



27
28
29
# File 'lib/harbor/daemon.rb', line 27

def log_file
  @log_file ||= @log_file_template.gsub('%PID', Process.pid.to_s)      
end

#runObject



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
82
83
84
85
86
# File 'lib/harbor/daemon.rb', line 42

def run
  @restart = false
  @alive = true

  # graceful restart
  trap(:HUP) do
    logger.info "Restarting gracefully." if logger
    @restart = true
    @alive = nil
    @worker.alive = nil
  end

  # graceful shutdown
  trap(:QUIT) do
    logger.info "Shutting down gracefully." if logger
    @alive = nil
    @worker.alive = nil
  end

  # quick exit
  [:TERM, :INT].each do |sig|
    trap(sig) do
      logger.info "Shutting down NOW" if logger
      cleanup!

      exit!(0)
    end
  end
  
  begin
    @worker.run
    sleep(@seconds_between_runs) if @alive
  end while @alive
    
  if @restart
    logger.info "Starting new daemon..."
    fork do
      Dir.chdir(START_CONTEXT[:cwd])
      exec(START_CONTEXT[:cmd], *START_CONTEXT[:argv])
    end
  end

  logger.info "Shutting down..." if logger
  cleanup!
end