Module: Octopusci::WorkerLauncher

Defined in:
lib/octopusci/worker_launcher.rb

Class Method Summary collapse

Class Method Details

.cleanup_existing_workersObject



6
7
8
9
10
11
12
13
14
# File 'lib/octopusci/worker_launcher.rb', line 6

def self.cleanup_existing_workers
  exist_worker_pids = get_worker_pids()
  puts "Cleaning up any existing workers... (#{exist_worker_pids.join(',')})"
  exist_worker_pids.each do |pid|
    wait_to_finish_and_exit(pid)
  end
  del_worker_pids
  puts "Finished cleaning up workers"
end

.del_worker_pidsObject



114
115
116
# File 'lib/octopusci/worker_launcher.rb', line 114

def self.del_worker_pids
  Resque.redis.del(pids_list_key())
end

.do_not_process_new_jobs(pid) ⇒ Object



93
94
95
# File 'lib/octopusci/worker_launcher.rb', line 93

def self.do_not_process_new_jobs(pid)
  kill("USR2", pid)
end

.get_worker_pidsObject



105
106
107
108
109
110
111
112
# File 'lib/octopusci/worker_launcher.rb', line 105

def self.get_worker_pids
  len = Resque.redis.llen(pids_list_key())
  if len > 0
    return Resque.redis.lrange(pids_list_key(), 0, len-1)
  else
    return []
  end
end

.immediately_kill_child(pid) ⇒ Object



89
90
91
# File 'lib/octopusci/worker_launcher.rb', line 89

def self.immediately_kill_child(pid)
  kill("USR1", pid)
end

.immediately_kill_child_and_exit(pid) ⇒ Object



85
86
87
# File 'lib/octopusci/worker_launcher.rb', line 85

def self.immediately_kill_child_and_exit(pid)
  kill("TERM", pid)
end

.kill(signal_str, pid) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/octopusci/worker_launcher.rb', line 72

def self.kill(signal_str, pid)
  begin
    Process.kill(signal_str, pid.to_i)
    puts "Sent '#{signal_str}' signal to worker with pid (#{pid})"
  rescue Errno::ESRCH => e
    puts "Failed to send '#{signal_str}' to worker with pid (#{pid}) - #{e.to_s}"
  end
end

.launchObject



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
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
# File 'lib/octopusci/worker_launcher.rb', line 16

def self.launch
  puts "Launching new workers..."

  # We need to disconnect the redis connection because when we fork and
  # each fork gets a copy of the same connection it is a problem and the
  # redis protocol will detect it and throw an exception. This is
  # necessary because each forked instance needs its own redis connection.
  # This only works because Resque.redis manages a singleton an instance
  # variable and if that instance variable isn't set then it reconnects
  # and returns the new connection.
  Resque.redis.quit

  if Octopusci::Config['general']['tentacles_user'] != nil
    require 'etc'
    chosen_user = Etc.getpwnam(Octopusci::Config['general']['tentacles_user'])
    if chosen_user
      # Switch the effective and real uid to the specified user
      Process.uid = chosen_user.uid
      Process.euid = chosen_user.uid

      # Set the USER, HOME, and SHELL environment variables to those found in /etc/passwd for the specified user.
      # This is important for some applications/scripts like RVM so that they can find things relative to the users home directory.
      ENV['USER'] = chosen_user.name
      ENV['SHELL'] = chosen_user.shell
      ENV['HOME'] = chosen_user.dir

      # Set the OCTOPUSCI environment variable applications to true so that programs instantiated by ocotpusci jobs could determine if
      # they are being run by octopusci or not.
      ENV['OCTOPUSCI'] = 'true'
    end
  end

  worker_pids = []
  
  Octopusci::Config['stages'].size.times do
    cur_pid = Process.fork do
      queues = ['octopusci:commit']
      worker = Resque::Worker.new(*queues)
      worker.log "Starting worker #{worker}"
      worker.work(5)
    end
    
    worker_pids << cur_pid
    
    Process.detach(cur_pid)
    
    puts "Launched worker with pid (#{cur_pid})"
  end
  
  worker_pids.each do |pid|
    push_worker_pid(pid)
  end
  
  puts "Finished launching workers"
end

.pids_list_keyObject



118
119
120
# File 'lib/octopusci/worker_launcher.rb', line 118

def self.pids_list_key
  "octopusci:workerpids"
end

.push_worker_pid(pid) ⇒ Object



101
102
103
# File 'lib/octopusci/worker_launcher.rb', line 101

def self.push_worker_pid(pid)
  Resque.redis.rpush(pids_list_key, pid)
end

.start_to_process_new_jobs_again(pid) ⇒ Object



97
98
99
# File 'lib/octopusci/worker_launcher.rb', line 97

def self.start_to_process_new_jobs_again(pid)
  kill("CONT", pid)
end

.wait_to_finish_and_exit(pid) ⇒ Object



81
82
83
# File 'lib/octopusci/worker_launcher.rb', line 81

def self.wait_to_finish_and_exit(pid)
  kill("QUIT", pid)
end