Class: Dante::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/dante/runner.rb

Constant Summary collapse

MAX_START_TRIES =
5

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, defaults = {}, &block) ⇒ Runner

Returns a new instance of Runner.



29
30
31
32
33
34
35
36
37
38
# File 'lib/dante/runner.rb', line 29

def initialize(name, defaults={}, &block)
  @name = name
  @startup_command = block
  @options = {
    :host => '0.0.0.0',
    :pid_path => "/var/run/#{@name}.pid",
    :log_path => false,
    :debug => true
  }.merge(defaults)
end

Instance Attribute Details

#descriptionObject

Returns the value of attribute description.



21
22
23
# File 'lib/dante/runner.rb', line 21

def description
  @description
end

#nameObject

Returns the value of attribute name.



21
22
23
# File 'lib/dante/runner.rb', line 21

def name
  @name
end

#optionsObject

Returns the value of attribute options.



21
22
23
# File 'lib/dante/runner.rb', line 21

def options
  @options
end

#verify_options_hookObject

Returns the value of attribute verify_options_hook.



21
22
23
# File 'lib/dante/runner.rb', line 21

def verify_options_hook
  @verify_options_hook
end

Class Method Details

.run(*args, &block) ⇒ Object



24
25
26
# File 'lib/dante/runner.rb', line 24

def run(*args, &block)
  self.new(*args, &block)
end

Instance Method Details

#daemon_running?Boolean

Returns running for the daemonized process self.daemon_running?

Returns:

  • (Boolean)


158
159
160
161
162
163
164
# File 'lib/dante/runner.rb', line 158

def daemon_running?
  return false unless File.exist?(options[:pid_path])
  Process.kill 0, File.read(options[:pid_path]).to_i
  true
rescue Errno::ESRCH
  false
end

#daemon_stopped?Boolean

Returns true if process is not running

Returns:

  • (Boolean)


152
153
154
# File 'lib/dante/runner.rb', line 152

def daemon_stopped?
  ! self.daemon_running?
end

#daemonizeObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/dante/runner.rb', line 78

def daemonize
  return log("Process is already started") if self.daemon_running? # daemon already started

  if !options[:log_path]
     options[:log_path] = "/var/log/#{@name}.log"
  end

  # Start process
  pid = fork do
    exit if fork
    Process.setsid
    exit if fork
    store_pid(Process.pid)
    File.umask 0000
    redirect_output!
    start
  end
  Process.waitpid pid
  # Ensure process is running
  if until_true(MAX_START_TRIES) { self.daemon_running? }
    log "Daemon has started successfully"
    true
  else # Failed to start
    log "Daemonized process couldn't be started"
    false
  end
end

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

Executes the runner based on options



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
# File 'lib/dante/runner.rb', line 49

def execute(opts={}, &block)
  parse_options
  self.options.merge!(opts)

  @verify_options_hook.call(self.options) if @verify_options_hook

  if options.include?(:kill)
    self.stop
  else # create process
    self.stop if options.include?(:restart)

    # If a username, uid, groupname, or gid is passed,
    # drop privileges accordingly.

    if options[:group]
      gid = options[:group].is_a?(Integer) ? options[:group] : Etc.getgrnam(options[:group]).gid
      Process::GID.change_privilege(gid)
    end

    if options[:user]
      uid = options[:user].is_a?(Integer) ? options[:user] : Etc.getpwnam(options[:user]).uid
      Process::UID.change_privilege(uid)
    end

    @startup_command = block if block_given?
    options[:daemonize] ? daemonize : start
  end
end

#interruptObject



142
143
144
145
146
147
148
149
# File 'lib/dante/runner.rb', line 142

def interrupt
  if options[:debug]
    raise Interrupt
    sleep 1
  else
    log "Interrupt received; stopping #{@name}"
  end
end

#restartObject



137
138
139
140
# File 'lib/dante/runner.rb', line 137

def restart
  self.stop
  self.start
end

#startObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/dante/runner.rb', line 106

def start
  log "Starting #{@name} service..."

  if log_path = options[:log_path] && options[:daemonize].nil?
     redirect_output! 
  end

  trap("INT") {
    interrupt
    exit
  }

  trap("TERM"){
    log "Trying to stop #{@name}..."
    exit
  }

  @startup_command.call(self.options) if @startup_command
end

#stop(kill_arg = nil) ⇒ Object

Stops a daemonized process



127
128
129
130
131
132
133
134
135
# File 'lib/dante/runner.rb', line 127

def stop(kill_arg=nil)
  if self.daemon_running?
    kill_pid(kill_arg || options[:kill])
    until_true(MAX_START_TRIES) { self.daemon_stopped? }
  else # not running
    log "No #{@name} processes are running"
    false
  end
end

#with_options(&block) ⇒ Object

Accepts options for the process



42
43
44
# File 'lib/dante/runner.rb', line 42

def with_options(&block)
  @with_options = block
end