Class: Workhorse::Daemon

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

Defined Under Namespace

Classes: ShellHandler, Worker

Instance Method Summary collapse

Constructor Details

#initialize(pidfile: nil, quiet: false) {|ScopedEnv.new(self, [:worker])| ... } ⇒ Daemon

Returns a new instance of Daemon.

Yields:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/workhorse/daemon.rb', line 15

def initialize(pidfile: nil, quiet: false, &_block)
  @pidfile = pidfile
  @quiet = quiet
  @workers = []

  yield ScopedEnv.new(self, [:worker])

  @count = @workers.count

  fail 'No workers are defined.' if @count < 1

  FileUtils.mkdir_p('tmp/pids')

  if @pidfile.nil?
    @pidfile = @count > 1 ? 'tmp/pids/workhorse.%i.pid' : 'tmp/pids/workhorse.pid'
  elsif @count > 1 && !@pidfile.include?('%s')
    fail 'Pidfile must include placeholder "%s" for worker id when specifying a count > 1.'
  elsif @count == 0 && @pidfile.include?('%s')
    fail 'Pidfile must not include placeholder "%s" for worker id when specifying a count of 1.'
  end
end

Instance Method Details

#restartObject



118
119
120
121
# File 'lib/workhorse/daemon.rb', line 118

def restart
  stop
  return start
end

#start(quiet: false) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/workhorse/daemon.rb', line 41

def start(quiet: false)
  code = 0

  for_each_worker do |worker|
    pid_file, pid = read_pid(worker)

    if pid_file && pid
      warn "Worker ##{worker.id} (#{worker.name}): Already started (PID #{pid})" unless quiet
      code = 1
    elsif pid_file
      File.delete pid_file
      puts "Worker ##{worker.id} (#{worker.name}): Starting (stale pid file)" unless quiet
      start_worker worker
    else
      warn "Worker ##{worker.id} (#{worker.name}): Starting" unless quiet
      start_worker worker
    end
  end

  return code
end

#status(quiet: false) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/workhorse/daemon.rb', line 84

def status(quiet: false)
  code = 0

  for_each_worker do |worker|
    pid_file, pid = read_pid(worker)

    if pid_file && pid
      puts "Worker ##{worker.id} (#{worker.name}): Running" unless quiet
    elsif pid_file
      warn "Worker ##{worker.id} (#{worker.name}): Not running (stale PID file)" unless quiet
      code = 1
    else
      warn "Worker ##{worker.id} (#{worker.name}): Not running" unless quiet
      code = 1
    end
  end

  return code
end

#stop(kill = false) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/workhorse/daemon.rb', line 63

def stop(kill = false)
  code = 0

  for_each_worker do |worker|
    pid_file, pid = read_pid(worker)

    if pid_file && pid
      puts "Worker (#{worker.name}) ##{worker.id}: Stopping"
      stop_worker pid_file, pid, kill
    elsif pid_file
      File.delete pid_file
      puts "Worker (#{worker.name}) ##{worker.id}: Already stopped (stale PID file)"
    else
      warn "Worker (#{worker.name}) ##{worker.id}: Already stopped"
      code = 1
    end
  end

  return code
end

#watchObject



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/workhorse/daemon.rb', line 104

def watch
  if defined?(Rails)
    should_be_running = !File.exist?(Rails.root.join('tmp/stop.txt'))
  else
    should_be_running = true
  end

  if should_be_running && status(quiet: true) != 0
    return start(quiet: Workhorse.silence_watcher)
  else
    return 0
  end
end

#worker(name = 'Job Worker', &block) ⇒ Object



37
38
39
# File 'lib/workhorse/daemon.rb', line 37

def worker(name = 'Job Worker', &block)
  @workers << Worker.new(@workers.size + 1, name, &block)
end