unicorn-wrangler 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 467ba192f3c2102dbc67f8fa957081576ca2e1a0
4
- data.tar.gz: 0e3fc78a240edc9c0c0982d60dc2579ecffff3a6
3
+ metadata.gz: 14daf7ce37b1e4cdc63918f515f1692df2d98288
4
+ data.tar.gz: bd3ad398853fb679a09063fe23e1fda243e1ffdb
5
5
  SHA512:
6
- metadata.gz: 5e7eebda41d84eb9a914a93ad9d8914591963877d8cc5d51c9d42b0e838f026e763317b8db0deccc9b316a5c5cbb3176ea9a2c72137ea5a9af02e7ee808d7c24
7
- data.tar.gz: 428f1680fea401c017cc88f6371457bcdf24cbd8dc2a14ad6035faa5adfd561cdfe7dc1317af53ea178f47864854325f7213421b97fceeebb1a5eb93a2c2e304
6
+ metadata.gz: ff65b1fd38f6c10e67949ed25496d3bdc78bd56b6def232bda911f3f0c55198791ae8b676046e4c6e93a7b51d416691ad15696dc673981ded7df782c30c82c2e
7
+ data.tar.gz: 4188b4cecd023e45041fcd8a19e5ff5171cea6f328314678cb72ade2e055944b9f82a95b0acdf1029a93c9feada53f9ef7ad195e611591af777eb903884e98e3
@@ -22,5 +22,5 @@ OptionParser.new do |opts|
22
22
  end
23
23
  end.parse!(ARGV[0...command_index])
24
24
 
25
- launcher = Unicorn::Wrangler.new command, options
25
+ launcher = Unicorn::Wrangler::Main.new command, options
26
26
  launcher.start
@@ -1,19 +1,47 @@
1
- require "unicorn/wrangler/version"
1
+ require 'unicorn/wrangler/version'
2
+ require 'logger'
2
3
 
3
4
  module Unicorn
4
5
  class Wrangler
5
- attr_reader :command, :pidfile, :grace_period
6
- attr_accessor :unicorn
7
-
8
- def initialize(command, options = {})
9
- @command = command
10
- @pidfile = File.expand_path(options[:pidfile] || 'unicorn.pid')
11
- @grace_period = options[:grace_period] || 60
12
- @verbose = options[:verbose]
13
- @unicorn = UnicornProcess.from_pidfile(@pidfile)
6
+ class << self
7
+ def logger
8
+ @logger ||= Logger.new(STDOUT)
9
+ end
10
+ end
11
+
12
+ module Utils
13
+ def warn(message)
14
+ Wrangler.logger.warn(message)
15
+ end
16
+
17
+ def debug(message)
18
+ Thread.new do
19
+ Wrangler.logger.debug(message)
20
+ end.join
21
+ end
22
+
23
+ def trap_signals(*signals, &block)
24
+ signals.map(&:to_s).each do |signal|
25
+ trap(signal) do
26
+ debug "received #{signal} (watching #{unicorn.pid})"
27
+ block.call signal
28
+ end
29
+ end
30
+ end
31
+
32
+ def wait_for(seconds, &block)
33
+ end_time = Time.now + seconds
34
+ until Time.now > end_time || block.call
35
+ sleep 0.1
36
+ end
37
+ block.call
38
+ end
14
39
  end
15
40
 
16
41
  class UnicornProcess
42
+ extend Utils
43
+ include Utils
44
+
17
45
  attr_reader :pid, :pidfile
18
46
 
19
47
  def initialize(pidfile)
@@ -29,30 +57,40 @@ module Unicorn
29
57
  end
30
58
 
31
59
  def signal(msg)
32
- puts "Sending signal #{msg} to #{pid}"
33
- Process.kill msg, pid
60
+ debug "Sending signal #{msg} to #{pid}"
61
+ Process.kill msg.to_s, pid
34
62
  end
35
63
 
36
64
  def reload(grace_period)
37
- signal "USR2"
38
- sleep grace_period
39
- reloaded_unicorn = UnicornProcess.from_pidfile(pidfile)
40
- if reloaded_unicorn && pid != reloaded_unicorn.pid
41
- terminate
65
+ signal :USR2
66
+ if wait_for(grace_period) { reloaded_unicorn }
67
+ Thread.new do
68
+ sleep grace_period
69
+ terminate
70
+ end
42
71
  reloaded_unicorn
43
72
  else
44
73
  raise "unicorn didn't reload correctly within grace period (was pid #{pid})"
45
74
  end
46
75
  end
47
76
 
77
+ def reloaded_unicorn
78
+ reloaded = UnicornProcess.from_pidfile(pidfile)
79
+ if reloaded && pid != reloaded.pid
80
+ reloaded
81
+ end
82
+ end
83
+
48
84
  def launch_assassin(grace_period)
49
85
  if running? && !@assassin_launched
50
86
  @assassin_launched = true
51
- puts "preparing to kill unicorn #{pid} in #{grace_period} seconds"
87
+ debug "preparing to kill unicorn #{pid} in #{grace_period} seconds"
52
88
  unless fork
89
+ $0 = "unicorn-wrangler (waiting to kill #{pid})"
53
90
  File.write(assassin_pidfile, Process.pid.to_s)
54
91
 
55
- trap 'TERM' do
92
+ trap_signals :TERM do
93
+ debug "Trapped and killed assassin"
56
94
  exit
57
95
  end
58
96
 
@@ -67,7 +105,9 @@ module Unicorn
67
105
  def recall_assassin
68
106
  if File.exist?(assassin_pidfile)
69
107
  assassin_pid = File.read(assassin_pidfile).to_i
70
- Process.kill 'TERM', assassin_pid
108
+ debug "Recalling assassin with pid #{assassin_pid}"
109
+ Process.kill 'KILL', assassin_pid
110
+ File.delete assassin_pidfile
71
111
  end
72
112
  rescue Errno::ESRCH
73
113
  end
@@ -78,29 +118,15 @@ module Unicorn
78
118
 
79
119
  def terminate
80
120
  if running?
81
- signal 'TERM'
121
+ signal :TERM
82
122
  else
83
- "Attempt to terminate #{pid} failed as process not running"
84
- end
85
- end
86
-
87
- def verbose(message)
88
- self.class.verbose(message)
89
- end
90
-
91
- def self.verbose(message)
92
- Unicorn::Wrangler.verbose(message)
93
- end
94
-
95
- def self.wait_for(&block)
96
- until block.call
97
- sleep 0.1
123
+ warn "Attempt to terminate #{pid} failed as process not running"
98
124
  end
99
125
  end
100
126
 
101
127
  def self.start(pidfile, command)
102
128
  Process.spawn(command, pgroup: true)
103
- wait_for { File.exist?(pidfile) }
129
+ wait_for(60) { File.exist?(pidfile) }
104
130
  new(pidfile)
105
131
  end
106
132
 
@@ -109,71 +135,61 @@ module Unicorn
109
135
  end
110
136
  end
111
137
 
112
- def start
113
- setup_signal_handlers
138
+ class Main
139
+ include Utils
140
+ extend Utils
114
141
 
115
- if unicorn && unicorn.running?
116
- self.unicorn = reload_unicorn
117
- else
118
- self.unicorn = UnicornProcess.start(pidfile, command)
119
- sleep grace_period
120
- end
142
+ attr_reader :command, :pidfile, :grace_period
143
+ attr_accessor :unicorn
121
144
 
122
- if unicorn.running?
123
- verbose "Unicorn running on #{unicorn.pid}"
124
- loop_while_unicorn_runs
125
- else
126
- verbose "Unable to start unicorn. Exiting."
145
+ def initialize(command, options = {})
146
+ @command = command
147
+ @pidfile = File.expand_path(options[:pidfile] || 'unicorn.pid')
148
+ @grace_period = options[:grace_period] || 60
149
+ Wrangler.logger.level = Logger::DEBUG if options[:verbose]
150
+ @unicorn = UnicornProcess.from_pidfile(@pidfile)
127
151
  end
128
- end
129
152
 
130
- def setup_signal_handlers
131
- trap_signals(:HUP) { reload_unicorn }
132
- trap_signals(:QUIT, :INT, :TERM) do |signal|
133
- kill_unicorn_after_delay
134
- exit
135
- end
136
- end
153
+ def start
154
+ $0 = 'unicorn-wrangler (starting up)'
155
+ setup_signal_handlers
137
156
 
138
- def reload_unicorn
139
- self.unicorn = unicorn.reload(grace_period) if unicorn
140
- end
157
+ if unicorn && unicorn.running?
158
+ self.unicorn = unicorn.reload(grace_period)
159
+ else
160
+ self.unicorn = UnicornProcess.start(pidfile, command)
161
+ wait_for(grace_period) { unicorn.running? }
162
+ end
141
163
 
142
- def loop_while_unicorn_runs
143
- loop do
144
164
  if unicorn.running?
145
- sleep 0.1
165
+ debug "Unicorn running on #{unicorn.pid}"
166
+ $0 = "unicorn-wrangler (monitoring #{unicorn.pid})"
167
+ loop_while_unicorn_runs
146
168
  else
147
- exit
169
+ debug "Unable to start unicorn. Exiting."
148
170
  end
149
171
  end
150
- end
151
172
 
152
- def trap_signals(*signals, &block)
153
- signals.map(&:to_s).each do |signal|
154
- trap(signal) do
155
- verbose "received #{signal} (managing #{unicorn.pid})"
156
- block.call signal
173
+ def setup_signal_handlers
174
+ trap_signals(:HUP) do
175
+ self.unicorn = unicorn.reload(grace_period) if unicorn
157
176
  end
158
- end
159
- end
160
177
 
161
- def wait_for(&block)
162
- until block.call
163
- sleep 0.1
178
+ trap_signals(:QUIT, :INT, :TERM) do |signal|
179
+ unicorn.launch_assassin(grace_period) if unicorn
180
+ exit
181
+ end
164
182
  end
165
- end
166
-
167
- def kill_unicorn_after_delay
168
- unicorn.launch_assassin(grace_period) if unicorn
169
- end
170
-
171
- def verbose(message)
172
- self.class.verbose(message)
173
- end
174
183
 
175
- def self.verbose(message)
176
- puts message if @verbose
184
+ def loop_while_unicorn_runs
185
+ loop do
186
+ if unicorn.running?
187
+ sleep 0.1
188
+ else
189
+ exit
190
+ end
191
+ end
192
+ end
177
193
  end
178
194
  end
179
195
  end
@@ -1,5 +1,5 @@
1
1
  module Unicorn
2
2
  class Wrangler
3
- VERSION = "0.0.7"
3
+ VERSION = "0.0.8"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn-wrangler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Ward
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-20 00:00:00.000000000 Z
11
+ date: 2013-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler