uc 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/uc +12 -7
- data/examples/unicorn.rb +44 -0
- data/lib/uc/config.rb +95 -0
- data/lib/uc/custom_logger.rb +24 -0
- data/lib/uc/event.rb +4 -0
- data/lib/uc/event_stream.rb +162 -0
- data/lib/uc/ext/string.rb +29 -0
- data/lib/uc/logger.rb +32 -19
- data/lib/uc/mqueue.rb +1 -1
- data/lib/uc/paths.rb +109 -0
- data/lib/uc/server.rb +60 -71
- data/lib/uc/shell_helper.rb +25 -1
- data/lib/uc/status.rb +49 -0
- data/lib/uc/templates/unicorn.erb +58 -0
- data/lib/uc/unicorn/api.rb +53 -29
- data/lib/uc/unicorn/config.rb +32 -72
- data/lib/uc/unicorn/gradual_shutdown.rb +57 -0
- data/lib/uc/unicorn/helper.rb +25 -0
- data/lib/uc/unicorn/init.rb +58 -0
- data/lib/uc/unicorn/paths.rb +54 -0
- data/lib/uc/unicorn/prestart.rb +35 -69
- data/lib/uc/unicorn/ready_event.rb +58 -0
- data/lib/uc/unicorn/ready_wait.rb +58 -0
- data/lib/uc/version.rb +1 -1
- data/patches/unicorn.patch +45 -0
- metadata +18 -4
- data/lib/uc/mq_logger.rb +0 -22
- data/lib/uc/unicorn/rolling_restart.rb +0 -87
data/lib/uc/server.rb
CHANGED
@@ -1,57 +1,49 @@
|
|
1
1
|
require 'uc/logger'
|
2
2
|
require 'uc/shell_helper'
|
3
|
-
require 'uc/
|
4
|
-
require 'uc/
|
3
|
+
require 'uc/config'
|
4
|
+
require 'uc/status'
|
5
5
|
require 'uc/unicorn/config'
|
6
|
+
require 'uc/unicorn/paths'
|
6
7
|
require 'uc/error'
|
8
|
+
require 'uc/paths'
|
7
9
|
|
8
10
|
module Uc
|
9
|
-
|
10
11
|
class Server
|
11
12
|
|
12
13
|
include ::Uc::ShellHelper
|
13
14
|
include ::Uc::Logger
|
14
15
|
|
15
|
-
attr_reader :
|
16
|
-
attr_reader :rails_env
|
16
|
+
attr_reader :paths, :rails_env, :app_dir
|
17
17
|
|
18
|
-
def initialize(app_dir, rails_env: "production")
|
19
|
-
@
|
18
|
+
def initialize(app_dir, rails_env: "production", debug: false)
|
19
|
+
@app_dir = app_dir
|
20
20
|
@rails_env = rails_env
|
21
|
-
@
|
22
|
-
end
|
23
|
-
|
24
|
-
def app_env(&block)
|
25
|
-
uconfig.dirs_checked? || uconfig.check_dirs
|
26
|
-
yield if block
|
21
|
+
@debug = debug
|
27
22
|
end
|
28
23
|
|
29
24
|
def start
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
cmd %{unicorn -c #{uconfig.
|
25
|
+
init_once
|
26
|
+
if server_status.running?
|
27
|
+
puts server_status
|
28
|
+
return
|
29
|
+
end
|
30
|
+
event_stream.watch_in_background :fin do
|
31
|
+
cmd %{unicorn -c #{uconfig.path} -D -E #{rails_env} }, return_output: false,
|
37
32
|
error_msg: "error starting unicorn"
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
41
36
|
def stop
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
kill(pid, 30)
|
37
|
+
init_once
|
38
|
+
if server_status.stopped?
|
39
|
+
logger.info "unicorn not running"
|
40
|
+
return
|
49
41
|
end
|
42
|
+
kill(server_status.pid, 30)
|
50
43
|
end
|
51
44
|
|
52
45
|
def status
|
53
|
-
|
54
|
-
puts status
|
46
|
+
puts server_status
|
55
47
|
end
|
56
48
|
|
57
49
|
def restart
|
@@ -60,65 +52,62 @@ module Uc
|
|
60
52
|
end
|
61
53
|
|
62
54
|
def rolling_restart
|
63
|
-
|
64
|
-
|
55
|
+
init_once
|
56
|
+
uconfig.generate_once
|
57
|
+
if not server_status.running?
|
65
58
|
start
|
66
59
|
return
|
67
60
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
raise ::Uc::Error, "timeout reached while waiting for server to restart"
|
61
|
+
event_stream.watch :fin do
|
62
|
+
Process.kill("USR2", server_status.pid)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def print_config
|
67
|
+
init_once
|
68
|
+
config.to_h.each do |k,v|
|
69
|
+
v = %{ "#{v}" } if not v.is_a? Numeric
|
70
|
+
puts "#{k} #{v}"
|
79
71
|
end
|
80
72
|
end
|
81
73
|
|
82
74
|
private
|
83
75
|
|
84
|
-
def
|
85
|
-
|
86
|
-
logger.debug "TERM signal sent to #{pid}"
|
87
|
-
(1..timeout).each do
|
88
|
-
if not process_running? pid
|
89
|
-
logger.info "Stopped #{pid}"
|
90
|
-
return
|
91
|
-
end
|
92
|
-
sleep 1
|
93
|
-
end
|
94
|
-
Process.kill(9, pid)
|
95
|
-
sleep 1
|
96
|
-
logger.info "Killed #{pid}"
|
76
|
+
def server_status
|
77
|
+
@server_status ||= ::Uc::Status.new(unicorn_paths)
|
97
78
|
end
|
98
79
|
|
80
|
+
def paths
|
81
|
+
@paths ||= ::Uc::Paths.new(app_dir)
|
82
|
+
end
|
99
83
|
|
100
|
-
def
|
101
|
-
|
102
|
-
Process.getpgid pid
|
103
|
-
return true
|
104
|
-
rescue Errno::ESRCH
|
105
|
-
return false
|
84
|
+
def config
|
85
|
+
@config ||= ::Uc::Config.new(app_dir)
|
106
86
|
end
|
107
87
|
|
108
|
-
def
|
109
|
-
|
88
|
+
def unicorn_paths
|
89
|
+
@unicorn_paths ||= ::Uc::Unicorn::Paths.new(config.app_dir)
|
110
90
|
end
|
111
91
|
|
112
|
-
def
|
113
|
-
uconfig.
|
92
|
+
def uconfig
|
93
|
+
@uconfig ||= ::Uc::Unicorn::Config.new(config.to_h, unicorn_paths)
|
114
94
|
end
|
115
95
|
|
116
|
-
def
|
117
|
-
@
|
118
|
-
|
119
|
-
|
120
|
-
|
96
|
+
def lock
|
97
|
+
@lock ||= ::Uc::Lock.new(app_dir)
|
98
|
+
end
|
99
|
+
|
100
|
+
def init
|
101
|
+
paths.validate_required
|
102
|
+
lock.acquire
|
103
|
+
::Uc::Logger.event_queue = config.event_queue_name
|
104
|
+
config.load_env
|
105
|
+
event_stream.debug_output = true if @debug
|
106
|
+
end
|
107
|
+
|
108
|
+
def init_once
|
109
|
+
@init_once ||= init
|
121
110
|
end
|
122
111
|
|
123
|
-
end
|
112
|
+
end
|
124
113
|
end
|
data/lib/uc/shell_helper.rb
CHANGED
@@ -2,7 +2,7 @@ module Uc
|
|
2
2
|
module ShellHelper
|
3
3
|
|
4
4
|
def cmd(command, error_msg: nil, return_output: false)
|
5
|
-
puts "Running #{command}"
|
5
|
+
puts "#{"Running".bold.green} #{command}"
|
6
6
|
if return_output
|
7
7
|
output = `#{command}`
|
8
8
|
else
|
@@ -15,5 +15,29 @@ module Uc
|
|
15
15
|
return output
|
16
16
|
end
|
17
17
|
|
18
|
+
def kill(pid, timeout)
|
19
|
+
Process.kill(:TERM, pid)
|
20
|
+
logger.debug "TERM signal sent to #{pid}"
|
21
|
+
(1..timeout).each do
|
22
|
+
if not process_running? pid
|
23
|
+
logger.info "Stopped #{pid}"
|
24
|
+
return
|
25
|
+
end
|
26
|
+
sleep 1
|
27
|
+
end
|
28
|
+
Process.kill(9, pid)
|
29
|
+
sleep 1
|
30
|
+
logger.info "Killed #{pid}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def process_running?(pid)
|
34
|
+
return false if pid <= 0
|
35
|
+
Process.getpgid pid
|
36
|
+
return true
|
37
|
+
rescue Errno::ESRCH
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
|
18
42
|
end
|
19
43
|
end
|
data/lib/uc/status.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'uc/shell_helper'
|
2
|
+
|
3
|
+
module Uc
|
4
|
+
class Status
|
5
|
+
|
6
|
+
include ::Uc::ShellHelper
|
7
|
+
|
8
|
+
attr_reader :paths
|
9
|
+
attr_accessor :use_pid
|
10
|
+
|
11
|
+
def initialize(unicorn_paths)
|
12
|
+
@paths = unicorn_paths
|
13
|
+
end
|
14
|
+
|
15
|
+
def running?
|
16
|
+
return process_running? pid if use_pid
|
17
|
+
not ex_lock_available?
|
18
|
+
end
|
19
|
+
|
20
|
+
def pid
|
21
|
+
@pid ||= read_pid
|
22
|
+
end
|
23
|
+
|
24
|
+
def stopped?
|
25
|
+
not running?
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
status = ( running? ? "Running pid #{pid}" : "Stopped")
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def ex_lock_available?
|
35
|
+
File.open( paths.lock_file, 'a+') do |f|
|
36
|
+
ex_lock = f.flock(File::LOCK_EX|File::LOCK_NB)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def read_pid
|
41
|
+
pid = (File.read paths.pid_file).to_i
|
42
|
+
pid == 0 ? -1 : pid
|
43
|
+
rescue
|
44
|
+
return -1
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'uc/unicorn/api'
|
2
|
+
uc = ::Uc::Unicorn::Api.new("<%= config.fetch :event_queue %>")
|
3
|
+
worker_processes <%= config.fetch :instances %>
|
4
|
+
working_directory "<%= paths.app_dir %>"
|
5
|
+
timeout <%= config.fetch :timeout %>
|
6
|
+
listen "<%= paths.socket %>" , :backlog => <%= config.fetch :queue_size %>
|
7
|
+
pid "<%= paths.pid_file %>"
|
8
|
+
stdout_path "<%= paths.stdout_log %>"
|
9
|
+
stderr_path "<%= paths.stderr_log %>"
|
10
|
+
|
11
|
+
ready_wait = <%= config.fetch :ready_wait %>
|
12
|
+
|
13
|
+
preload_app true
|
14
|
+
|
15
|
+
GC.respond_to?(:copy_on_write_friendly=) and
|
16
|
+
GC.copy_on_write_friendly = true
|
17
|
+
|
18
|
+
check_client_connection false
|
19
|
+
|
20
|
+
before_fork do |server, worker|
|
21
|
+
|
22
|
+
uc.init(server)
|
23
|
+
|
24
|
+
defined?(ActiveRecord::Base) and
|
25
|
+
ActiveRecord::Base.connection.disconnect!
|
26
|
+
|
27
|
+
if defined?(Resque)
|
28
|
+
Resque.redis.quit
|
29
|
+
Rails.logger.info('Disconnected from Redis')
|
30
|
+
end
|
31
|
+
|
32
|
+
uc.wait_for_worker_ready(server, worker, ready_wait: ready_wait)
|
33
|
+
uc.gradual_shutdown(server, worker)
|
34
|
+
sleep 0.3
|
35
|
+
end
|
36
|
+
|
37
|
+
after_fork do |server, worker|
|
38
|
+
defined?(ActiveRecord::Base) and
|
39
|
+
ActiveRecord::Base.establish_connection
|
40
|
+
|
41
|
+
uc.prestart server, worker, url: "<%= config.fetch :prestart_url %>"
|
42
|
+
uc.send_worker_ready server, worker, ready_wait: ready_wait
|
43
|
+
uc.end_run worker
|
44
|
+
end
|
45
|
+
|
46
|
+
before_exec do |server|
|
47
|
+
uc.clean_env
|
48
|
+
uc.load_env
|
49
|
+
end
|
50
|
+
|
51
|
+
if respond_to? :on_exec_fail
|
52
|
+
uc = uc
|
53
|
+
on_exec_fail do |server|
|
54
|
+
puts "runnign asdadad"
|
55
|
+
uc.on_exec_fail
|
56
|
+
puts "lol"
|
57
|
+
end
|
58
|
+
end
|
data/lib/uc/unicorn/api.rb
CHANGED
@@ -1,30 +1,71 @@
|
|
1
|
-
require 'uc/
|
1
|
+
require 'uc/config'
|
2
|
+
require 'uc/unicorn/init'
|
3
|
+
require 'uc/unicorn/gradual_shutdown'
|
2
4
|
require 'uc/unicorn/prestart'
|
5
|
+
require 'uc/unicorn/ready_event'
|
6
|
+
require 'uc/unicorn/ready_wait'
|
3
7
|
require 'securerandom'
|
8
|
+
require 'uc/logger'
|
4
9
|
|
5
10
|
module Uc; module Unicorn
|
6
11
|
|
7
12
|
class Api
|
8
13
|
|
9
14
|
attr_reader :run_id
|
15
|
+
attr_accessor :queue_name
|
10
16
|
|
11
|
-
def initialize
|
17
|
+
def initialize(event_queue)
|
18
|
+
@queue_name = event_queue
|
12
19
|
@run_id = SecureRandom.hex(3)
|
20
|
+
::Uc::Logger.event_queue = queue_name
|
13
21
|
end
|
14
|
-
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
rolling_restart.run
|
22
|
+
|
23
|
+
def init(server)
|
24
|
+
@init ||= ::Uc::Unicorn::Init.new(server)
|
25
|
+
@init.run_once
|
19
26
|
end
|
20
27
|
|
28
|
+
def gradual_shutdown(server, worker)
|
29
|
+
gradual_shutdown = ::Uc::Unicorn::GradualShutdown.new(server, worker)
|
30
|
+
gradual_shutdown.run
|
31
|
+
end
|
21
32
|
|
22
33
|
def prestart(server, worker, **kwargs)
|
23
|
-
prestart = ::Uc::Unicorn::Prestart.new(server, worker,
|
24
|
-
prestart.run_id = @run_id
|
34
|
+
prestart = ::Uc::Unicorn::Prestart.new(server, worker, **kwargs)
|
25
35
|
prestart.run
|
26
36
|
end
|
27
37
|
|
38
|
+
def send_worker_ready(server, worker, **kwargs)
|
39
|
+
ready_event = ::Uc::Unicorn::ReadyEvent.new(server, worker, **kwargs)
|
40
|
+
ready_event.run_id = run_id
|
41
|
+
ready_event.run
|
42
|
+
end
|
43
|
+
|
44
|
+
def wait_for_worker_ready(server, worker, **kwargs)
|
45
|
+
ready_event_wait = ::Uc::Unicorn::ReadyWait.new(server, worker, **kwargs)
|
46
|
+
ready_event_wait.run_id = run_id
|
47
|
+
ready_event_wait.run
|
48
|
+
end
|
49
|
+
|
50
|
+
def acquire_shared_lock(lock_file)
|
51
|
+
shared_lock = ::Uc::Unicorn::Lock.new(lock_file)
|
52
|
+
shared_lock.acquire
|
53
|
+
end
|
54
|
+
|
55
|
+
def shared_env
|
56
|
+
@shared_env ||= {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def end_run(worker)
|
60
|
+
@init.end_run(worker)
|
61
|
+
end
|
62
|
+
|
63
|
+
def on_exec_fail
|
64
|
+
event_stream = ::Uc::Logger.event_stream
|
65
|
+
event_stream.close_connections
|
66
|
+
event_stream.fatal "re-exec failed"
|
67
|
+
end
|
68
|
+
|
28
69
|
def clean_env
|
29
70
|
ENV.delete "BUNDLE_BIN_PATH"
|
30
71
|
ENV.delete "RUBYLIB"
|
@@ -33,26 +74,9 @@ module Uc; module Unicorn
|
|
33
74
|
ENV.delete "GEM_PATH"
|
34
75
|
end
|
35
76
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def queue_name_from_file
|
45
|
-
queue_file = Pathname.new queue_name_file
|
46
|
-
queue_name = nil
|
47
|
-
if queue_file.readable?
|
48
|
-
queue_name = File.read(queue_file).chomp
|
49
|
-
queue_name = (queue_name.empty? ? nil : queue_name)
|
50
|
-
end
|
51
|
-
return queue_name
|
52
|
-
end
|
53
|
-
|
54
|
-
def queue_name_file
|
55
|
-
"config/unicorn_mq"
|
77
|
+
def load_env
|
78
|
+
config = ::Uc::Config.new(Dir.pwd)
|
79
|
+
config.load_env
|
56
80
|
end
|
57
81
|
|
58
82
|
end
|
data/lib/uc/unicorn/config.rb
CHANGED
@@ -1,86 +1,46 @@
|
|
1
|
-
require 'pathname'
|
2
1
|
require 'uc/logger'
|
3
|
-
|
4
|
-
|
2
|
+
require 'uc/error'
|
3
|
+
require 'erb'
|
5
4
|
|
6
|
-
|
5
|
+
module Uc
|
6
|
+
module Unicorn
|
7
7
|
|
8
|
-
|
8
|
+
class Config
|
9
9
|
|
10
|
-
|
11
|
-
@app_dir = app_dir
|
12
|
-
end
|
13
|
-
|
14
|
-
def config_path
|
15
|
-
rpath "config/unicorn.rb"
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
def stdout_log
|
20
|
-
rpath "log/unicorn.stdout.log"
|
21
|
-
end
|
22
|
-
|
23
|
-
def stderr_log
|
24
|
-
rpath "log/unicorn.stderr.log"
|
25
|
-
end
|
26
|
-
|
27
|
-
def socket_file
|
28
|
-
rpath "tmp/sockets/unicorn.sock"
|
29
|
-
end
|
30
|
-
|
31
|
-
def pid_file
|
32
|
-
rpath "tmp/pids/unicorn.pid"
|
33
|
-
end
|
10
|
+
include ::Uc::Logger
|
34
11
|
|
35
|
-
|
36
|
-
rpath "config.ru"
|
37
|
-
end
|
38
|
-
|
39
|
-
def read_pid
|
40
|
-
pid = (File.read pid_file).to_i
|
41
|
-
pid == 0 ? -1 : pid
|
42
|
-
rescue
|
43
|
-
return -1
|
44
|
-
end
|
12
|
+
attr_reader :paths, :config
|
45
13
|
|
46
|
-
|
47
|
-
|
48
|
-
|
14
|
+
def initialize(config_hash, paths)
|
15
|
+
@config = config_hash
|
16
|
+
@paths = paths
|
17
|
+
end
|
49
18
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
Dir.chdir app_dir do
|
54
|
-
raise ::Uc::Error, %{no config.ru found in app_dir} if not path_readable? rack_path
|
55
|
-
raise ::Uc::Error, %{no unicorn config found %} if not path_readable? config_path
|
19
|
+
def path
|
20
|
+
generate_once
|
21
|
+
paths.unicorn_config
|
56
22
|
end
|
57
|
-
@dirs_checked = true
|
58
|
-
end
|
59
|
-
|
60
|
-
def dirs_checked?
|
61
|
-
@dirs_checked
|
62
|
-
end
|
63
23
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
24
|
+
def generate_config_file
|
25
|
+
erb = ERB.new(File.read(paths.unicorn_template))
|
26
|
+
binding = Kernel.binding
|
27
|
+
File.open(paths.unicorn_config, 'w') do |f|
|
28
|
+
f.write erb.result(binding)
|
29
|
+
end
|
30
|
+
return true
|
31
|
+
rescue => e
|
32
|
+
logger.debug e.message
|
33
|
+
raise ::Uc::Error, "unable to generate unicorn config"
|
34
|
+
end
|
70
35
|
|
71
|
-
|
36
|
+
def generate_once
|
37
|
+
return if @config_generated
|
38
|
+
generate_config_file
|
39
|
+
@config_generated = true
|
40
|
+
end
|
72
41
|
|
73
|
-
def rpath(path)
|
74
|
-
path = Pathname.new(path)
|
75
|
-
raise "absolute path specified: #{path}" if path.absolute?
|
76
|
-
"#{app_dir}/#{path}"
|
77
|
-
end
|
78
42
|
|
79
|
-
def path_readable?(path_str)
|
80
|
-
path = Pathname.new(path_str)
|
81
|
-
path.readable?
|
82
43
|
end
|
83
44
|
|
84
|
-
|
85
|
-
|
86
|
-
end; end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'uc/logger'
|
2
|
+
require 'uc/unicorn/helper'
|
3
|
+
|
4
|
+
module Uc
|
5
|
+
module Unicorn
|
6
|
+
|
7
|
+
class GradualShutdown
|
8
|
+
|
9
|
+
include ::Uc::Logger
|
10
|
+
include ::Uc::Unicorn::Helper
|
11
|
+
|
12
|
+
attr_reader :server, :worker
|
13
|
+
|
14
|
+
def initialize(server, worker)
|
15
|
+
@server = server
|
16
|
+
@worker = worker
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
return if not (server && worker)
|
21
|
+
return if not restart?
|
22
|
+
shutdown_old_master
|
23
|
+
end
|
24
|
+
|
25
|
+
def shutdown_old_master
|
26
|
+
event_stream.debug "stopping old worker #{id}"
|
27
|
+
if send_signal
|
28
|
+
event_stream.debug "stopped old worker #{id}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def sig
|
33
|
+
(worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
|
34
|
+
end
|
35
|
+
|
36
|
+
def send_signal
|
37
|
+
Process.kill(sig, File.read(old_pid).to_i)
|
38
|
+
return true
|
39
|
+
rescue => e
|
40
|
+
log_kill_error e
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
def log_kill_error(e)
|
45
|
+
stderr.info "error sending kill signal #{id}| #{e.class} #{e.message}"
|
46
|
+
event_stream.warn "error while stopping worker #{worker.nr + 1}, #{e.class}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def id
|
50
|
+
@id ||= (worker.nr + 1)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Uc
|
2
|
+
module Unicorn
|
3
|
+
module Helper
|
4
|
+
|
5
|
+
def restart?
|
6
|
+
(File.readable? old_pid) && (server.pid != old_pid)
|
7
|
+
end
|
8
|
+
|
9
|
+
def first_worker?
|
10
|
+
worker.nr == 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def last_worker?
|
14
|
+
(worker.nr + 1) == server.worker_processes
|
15
|
+
end
|
16
|
+
|
17
|
+
def old_pid
|
18
|
+
"#{server.config[:pid]}.oldbin"
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'uc/unicorn/helper'
|
2
|
+
require 'uc/error'
|
3
|
+
require 'uc/logger'
|
4
|
+
|
5
|
+
module Uc
|
6
|
+
module Unicorn
|
7
|
+
class Init
|
8
|
+
|
9
|
+
include ::Uc::Logger
|
10
|
+
include ::Uc::Unicorn::Helper
|
11
|
+
|
12
|
+
attr_accessor :server, :worker
|
13
|
+
|
14
|
+
def initialize(server)
|
15
|
+
@server = server
|
16
|
+
end
|
17
|
+
|
18
|
+
def event_type
|
19
|
+
@event_type ||= (restart? ? "restart" : "start")
|
20
|
+
end
|
21
|
+
|
22
|
+
def lock_file
|
23
|
+
@lock_file ||= "tmp/unicorn.lock"
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
event_stream.debug "event_type #{event_type}"
|
28
|
+
acquired = acquire_lock
|
29
|
+
if not acquired
|
30
|
+
error_msg = "unable to acquire shared lock (unicorn)"
|
31
|
+
event_stream.fatal error_msg
|
32
|
+
raise ::Uc::Error, error_msg
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def acquire_lock
|
37
|
+
lock_acquired = File.new(lock_file, "a+").flock(File::LOCK_SH | File::LOCK_NB )
|
38
|
+
rescue => e
|
39
|
+
stderr.error "#{e.class} #{e.message}\n #{e.backtrace.join("\n")}"
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_once
|
44
|
+
return if @ran_once
|
45
|
+
@ran_once = true
|
46
|
+
run
|
47
|
+
end
|
48
|
+
|
49
|
+
def end_run(worker)
|
50
|
+
@worker = worker
|
51
|
+
if last_worker?
|
52
|
+
event_stream.pub :fin, "server #{event_type}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|