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

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)


147
148
149
150
151
152
153
# File 'lib/dante/runner.rb', line 147

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)


141
142
143
# File 'lib/dante/runner.rb', line 141

def daemon_stopped?
  ! self.daemon_running?
end

#daemonizeObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/dante/runner.rb', line 76

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

  # Start process
  pid = fork do
    exit if fork
    Process.setsid
    exit if fork
    store_pid(Process.pid)
    File.umask 0000
    redirect_output!
    start
  end
  # 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
# File 'lib/dante/runner.rb', line 49

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

  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



131
132
133
134
135
136
137
138
# File 'lib/dante/runner.rb', line 131

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

#restartObject



126
127
128
129
# File 'lib/dante/runner.rb', line 126

def restart
  self.stop
  self.start
end

#startObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/dante/runner.rb', line 99

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

  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



116
117
118
119
120
121
122
123
124
# File 'lib/dante/runner.rb', line 116

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