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
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'uc/logger'
|
3
|
+
|
4
|
+
module Uc
|
5
|
+
module Unicorn
|
6
|
+
class Paths
|
7
|
+
|
8
|
+
include ::Uc::Logger
|
9
|
+
|
10
|
+
attr_reader :app_dir
|
11
|
+
|
12
|
+
def initialize(app_dir)
|
13
|
+
@app_dir = app_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
def stdout_log
|
17
|
+
rpath "log/unicorn.stdout.log"
|
18
|
+
end
|
19
|
+
|
20
|
+
def stderr_log
|
21
|
+
rpath "log/unicorn.stderr.log"
|
22
|
+
end
|
23
|
+
|
24
|
+
def socket
|
25
|
+
rpath "tmp/sockets/unicorn.sock"
|
26
|
+
end
|
27
|
+
|
28
|
+
def pid_file
|
29
|
+
rpath "tmp/pids/unicorn.pid"
|
30
|
+
end
|
31
|
+
|
32
|
+
def lock_file
|
33
|
+
rpath "tmp/unicorn.lock"
|
34
|
+
end
|
35
|
+
|
36
|
+
def unicorn_config
|
37
|
+
rpath "tmp/unicorn_config.rb"
|
38
|
+
end
|
39
|
+
|
40
|
+
def unicorn_template
|
41
|
+
"#{__dir__}/../templates/unicorn.erb"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def rpath(path)
|
47
|
+
"#{app_dir}/#{path}"
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/uc/unicorn/prestart.rb
CHANGED
@@ -1,83 +1,49 @@
|
|
1
1
|
require 'uc/logger'
|
2
|
-
|
2
|
+
module Uc
|
3
|
+
module Unicorn
|
4
|
+
class Prestart
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
+
include ::Uc::Logger
|
7
|
+
attr_reader :server, :worker, :url
|
6
8
|
|
7
|
-
include ::Uc::Logger
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def app
|
21
|
-
@app ||= server.instance_variable_get("@app")
|
22
|
-
end
|
23
|
-
|
24
|
-
def run
|
25
|
-
response = app.call(rack_request)
|
26
|
-
body = response[2]
|
27
|
-
body.close
|
28
|
-
end_prestart
|
29
|
-
rescue => e
|
30
|
-
logger.warn "pre start failed for worker : #{e.message}"
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def worker_id
|
37
|
-
worker.nr + 1
|
38
|
-
end
|
39
|
-
|
40
|
-
def rack_request
|
41
|
-
Rack::MockRequest.env_for("http://127.0.0.1/#{url}")
|
42
|
-
end
|
10
|
+
def initialize(server, worker, url: "/")
|
11
|
+
@server = server
|
12
|
+
@worker = worker
|
13
|
+
@url = url
|
14
|
+
end
|
15
|
+
|
16
|
+
def app
|
17
|
+
@app ||= server.instance_variable_get("@app")
|
18
|
+
end
|
43
19
|
|
44
|
-
|
45
|
-
|
46
|
-
|
20
|
+
def run
|
21
|
+
make_prestart_request
|
22
|
+
end
|
47
23
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
24
|
+
def make_prestart_request
|
25
|
+
event_stream.debug "prestarting worker #{id}"
|
26
|
+
response = app.call(rack_request)
|
27
|
+
body = response[2]
|
28
|
+
if body.is_a? Rack::BodyProxy
|
29
|
+
body.close
|
30
|
+
end
|
31
|
+
|
32
|
+
event_stream.debug "worker #{id} prestart successful"
|
33
|
+
rescue => e
|
34
|
+
event_stream.warn "prestart failed for worker #{id}, #{e.class}"
|
52
35
|
end
|
53
|
-
logger.debug "[ps] start #{worker_id}"
|
54
|
-
send_prestart_end
|
55
|
-
mq_log "prestart end worker #{worker_id}"
|
56
|
-
logger.debug "[ps] end #{worker_id}"
|
57
|
-
end
|
58
36
|
|
59
|
-
|
60
|
-
|
61
|
-
mq.clear
|
62
|
-
mq.nb_writer do |writer|
|
63
|
-
writer.send prestart_end_event
|
37
|
+
def id
|
38
|
+
@id ||= worker.nr + 1
|
64
39
|
end
|
65
|
-
rescue Errno::ENOENT, Errno::EAGAIN, Errno::EACCES => e
|
66
|
-
logger.warn "prestart failed for worker #{worker.nr + 1}: #{e.class}"
|
67
|
-
end
|
68
40
|
|
69
|
-
|
70
|
-
run_id ? "prestart_end_#{run_id}" : "prestart_end"
|
71
|
-
end
|
41
|
+
private
|
72
42
|
|
73
|
-
|
74
|
-
|
75
|
-
|
43
|
+
def rack_request
|
44
|
+
Rack::MockRequest.env_for("http://127.0.0.1/#{url}")
|
45
|
+
end
|
76
46
|
|
77
|
-
def prestart_queue_name
|
78
|
-
"#{queue_name}_prestart_#{worker.nr}"
|
79
47
|
end
|
80
|
-
|
81
48
|
end
|
82
|
-
end
|
83
|
-
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'uc/logger'
|
2
|
+
require 'uc/mqueue'
|
3
|
+
require 'uc/unicorn/helper'
|
4
|
+
|
5
|
+
module Uc
|
6
|
+
module Unicorn
|
7
|
+
class ReadyEvent
|
8
|
+
|
9
|
+
include ::Uc::Logger
|
10
|
+
include ::Uc::Unicorn::Helper
|
11
|
+
|
12
|
+
attr_accessor :run_id
|
13
|
+
attr_reader :ready_wait, :server, :worker
|
14
|
+
|
15
|
+
|
16
|
+
def initialize(server, worker, run_id: nil, ready_wait: nil)
|
17
|
+
@server = server
|
18
|
+
@worker = worker
|
19
|
+
@run_id = run_id
|
20
|
+
@ready_wait = ready_wait
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
event_stream.info "worker #{id} ready"
|
25
|
+
if not last_worker?
|
26
|
+
notify if ready_wait
|
27
|
+
end
|
28
|
+
# event_stream.pub :fin, "server #{server_event} successful"
|
29
|
+
end
|
30
|
+
|
31
|
+
def queue_name
|
32
|
+
@queue_name ||= "#{event_queue}_ready_#{worker.nr + 1}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def id
|
36
|
+
@id ||= worker.nr + 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def notify
|
40
|
+
mq.create
|
41
|
+
msg = mq.nb_writer do |writer|
|
42
|
+
writer.send event
|
43
|
+
end
|
44
|
+
rescue Errno::ENOENT, Errno::EAGAIN, Errno::EACCES => e
|
45
|
+
event_stream.warn "ready event not sent for worker #{id}: #{e.class}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def event
|
49
|
+
run_id ? "ready_#{run_id}" : "ready"
|
50
|
+
end
|
51
|
+
|
52
|
+
def mq
|
53
|
+
@mq ||= ::Uc::Mqueue.new(queue_name, max_msg: 10, msg_size: 30)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'uc/mqueue'
|
2
|
+
require 'uc/logger'
|
3
|
+
require 'uc/unicorn/helper'
|
4
|
+
|
5
|
+
module Uc
|
6
|
+
module Unicorn
|
7
|
+
class ReadyWait
|
8
|
+
|
9
|
+
include ::Uc::Logger
|
10
|
+
include ::Uc::Unicorn::Helper
|
11
|
+
|
12
|
+
|
13
|
+
attr_accessor :run_id
|
14
|
+
attr_reader :ready_wait, :server, :worker
|
15
|
+
|
16
|
+
|
17
|
+
def initialize(server, worker, run_id: nil, ready_wait: ready_wait)
|
18
|
+
@server = server
|
19
|
+
@worker = worker
|
20
|
+
@run_id = run_id
|
21
|
+
@ready_wait = ready_wait
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
wait if ready_wait
|
26
|
+
end
|
27
|
+
|
28
|
+
def queue_name
|
29
|
+
@queue_name ||= "#{event_queue}_ready_#{worker.nr}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def id
|
33
|
+
@id ||= worker.nr + 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def wait
|
37
|
+
if first_worker?
|
38
|
+
event_stream.debug "no wait for worker #{worker.nr}"
|
39
|
+
return
|
40
|
+
end
|
41
|
+
mq.create
|
42
|
+
msg = mq.wait(event, ready_wait)
|
43
|
+
event_stream.debug "ack worker ready #{worker.nr}"
|
44
|
+
rescue Errno::ENOENT, Errno::EAGAIN, Errno::EACCES, Errno::ETIMEDOUT => e
|
45
|
+
event_stream.warn "ready wait error #{worker.nr}: #{e.class}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def event
|
49
|
+
run_id ? "ready_#{run_id}" : "ready"
|
50
|
+
end
|
51
|
+
|
52
|
+
def mq
|
53
|
+
@mq ||= ::Uc::Mqueue.new(queue_name, max_msg: 10, msg_size: 30)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/uc/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
[1mdiff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb[m
|
2
|
+
[1mindex 9406223..3ed9cbd 100644[m
|
3
|
+
[1m--- a/lib/unicorn/configurator.rb[m
|
4
|
+
[1m+++ b/lib/unicorn/configurator.rb[m
|
5
|
+
[36m@@ -171,6 +171,10 @@[m [mclass Unicorn::Configurator[m
|
6
|
+
set_hook(:before_exec, block_given? ? block : args[0], 1)[m
|
7
|
+
end[m
|
8
|
+
[m
|
9
|
+
[32m+[m[32m def on_exec_fail(*args, &block)[m
|
10
|
+
[32m+[m[32m set_hook(:on_exec_fail, block_given? ? block : args[0], 1)[m
|
11
|
+
[32m+[m[32m end[m
|
12
|
+
[32m+[m
|
13
|
+
# sets the timeout of worker processes to +seconds+. Workers[m
|
14
|
+
# handling the request/app.call/response cycle taking longer than[m
|
15
|
+
# this time period will be forcibly killed (via SIGKILL). This[m
|
16
|
+
[1mdiff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb[m
|
17
|
+
[1mindex a0ca302..4a1958d 100644[m
|
18
|
+
[1m--- a/lib/unicorn/http_server.rb[m
|
19
|
+
[1m+++ b/lib/unicorn/http_server.rb[m
|
20
|
+
[36m@@ -14,6 +14,7 @@[m [mclass Unicorn::HttpServer[m
|
21
|
+
# :stopdoc:[m
|
22
|
+
attr_accessor :app, :request, :timeout, :worker_processes,[m
|
23
|
+
:before_fork, :after_fork, :before_exec,[m
|
24
|
+
[32m+[m[32m :on_exec_fail, :on_exec_fail_safe,[m
|
25
|
+
:listener_opts, :preload_app,[m
|
26
|
+
:reexec_pid, :orig_app, :init_listeners,[m
|
27
|
+
:master_pid, :config, :ready_pipe, :user[m
|
28
|
+
[36m@@ -408,6 +409,7 @@[m [mclass Unicorn::HttpServer[m
|
29
|
+
self.reexec_pid = 0[m
|
30
|
+
self.pid = pid.chomp('.oldbin') if pid[m
|
31
|
+
proc_name 'master'[m
|
32
|
+
[32m+[m[32m on_exec_fail.call(self)[m
|
33
|
+
else[m
|
34
|
+
worker = WORKERS.delete(wpid) and worker.close rescue nil[m
|
35
|
+
m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"[m
|
36
|
+
[36m@@ -810,4 +812,9 @@[m [mclass Unicorn::HttpServer[m
|
37
|
+
raise ArgumentError, "no listeners" if LISTENERS.empty?[m
|
38
|
+
NEW_LISTENERS.clear[m
|
39
|
+
end[m
|
40
|
+
[32m+[m
|
41
|
+
[32m+[m[32m def on_exec_fail_safe[m
|
42
|
+
[32m+[m[32m on_exec_fail.call(self)[m
|
43
|
+
[32m+[m[32m rescue[m
|
44
|
+
[32m+[m[32m end[m
|
45
|
+
end[m
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Neeraj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,19 +66,33 @@ files:
|
|
66
66
|
- README.md
|
67
67
|
- Rakefile
|
68
68
|
- bin/uc
|
69
|
+
- examples/unicorn.rb
|
69
70
|
- lib/uc.rb
|
71
|
+
- lib/uc/config.rb
|
72
|
+
- lib/uc/custom_logger.rb
|
70
73
|
- lib/uc/error.rb
|
74
|
+
- lib/uc/event.rb
|
75
|
+
- lib/uc/event_stream.rb
|
76
|
+
- lib/uc/ext/string.rb
|
71
77
|
- lib/uc/lock.rb
|
72
78
|
- lib/uc/logger.rb
|
73
|
-
- lib/uc/mq_logger.rb
|
74
79
|
- lib/uc/mqueue.rb
|
80
|
+
- lib/uc/paths.rb
|
75
81
|
- lib/uc/server.rb
|
76
82
|
- lib/uc/shell_helper.rb
|
83
|
+
- lib/uc/status.rb
|
84
|
+
- lib/uc/templates/unicorn.erb
|
77
85
|
- lib/uc/unicorn/api.rb
|
78
86
|
- lib/uc/unicorn/config.rb
|
87
|
+
- lib/uc/unicorn/gradual_shutdown.rb
|
88
|
+
- lib/uc/unicorn/helper.rb
|
89
|
+
- lib/uc/unicorn/init.rb
|
90
|
+
- lib/uc/unicorn/paths.rb
|
79
91
|
- lib/uc/unicorn/prestart.rb
|
80
|
-
- lib/uc/unicorn/
|
92
|
+
- lib/uc/unicorn/ready_event.rb
|
93
|
+
- lib/uc/unicorn/ready_wait.rb
|
81
94
|
- lib/uc/version.rb
|
95
|
+
- patches/unicorn.patch
|
82
96
|
- uc.gemspec
|
83
97
|
homepage: ''
|
84
98
|
licenses:
|
data/lib/uc/mq_logger.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Uc
|
2
|
-
class MqLogger
|
3
|
-
|
4
|
-
attr_reader :queue_name
|
5
|
-
|
6
|
-
def initialize(queue_name)
|
7
|
-
@queue_name = queue_name
|
8
|
-
end
|
9
|
-
|
10
|
-
def mq
|
11
|
-
@mq ||= ::Uc::Mqueue.new(queue_name)
|
12
|
-
end
|
13
|
-
|
14
|
-
def log(msg)
|
15
|
-
@writer ||= mq.nb_writer
|
16
|
-
@writer.send msg
|
17
|
-
rescue Errno::ENOENT, Errno::EAGAIN, Errno::EACCES, Errno::EMSGSIZE => e
|
18
|
-
puts "#{e.class} #{e.message}"
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'uc/mqueue'
|
2
|
-
require 'uc/logger'
|
3
|
-
module Uc; module Unicorn
|
4
|
-
class RollingRestart
|
5
|
-
|
6
|
-
include ::Uc::Logger
|
7
|
-
attr_reader :server, :worker, :queue_name, :prestart_wait, :sleep_secs
|
8
|
-
attr_accessor :run_id
|
9
|
-
|
10
|
-
def initialize(server, worker, queue_name, prestart_wait: nil, sleep_secs: 0.1)
|
11
|
-
@server = server
|
12
|
-
@worker = worker
|
13
|
-
@queue_name = queue_name
|
14
|
-
@prestart_wait = prestart_wait
|
15
|
-
@sleep_secs = sleep_secs
|
16
|
-
end
|
17
|
-
|
18
|
-
def run
|
19
|
-
return if not (server && worker)
|
20
|
-
return if not restart?
|
21
|
-
|
22
|
-
destroy_prestart_queues
|
23
|
-
wait_for_prestart_end_event
|
24
|
-
sleep sleep_secs if not first_worker?
|
25
|
-
kill_old_worker
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def prestart_mq
|
31
|
-
@prestart_mq ||= ::Uc::Mqueue.new(prestart_queue, max_msg: 10, msg_size: 30)
|
32
|
-
end
|
33
|
-
|
34
|
-
def destroy_prestart_queues
|
35
|
-
return if not first_worker?
|
36
|
-
(0..server.worker_processes).each do |i|
|
37
|
-
mq = ::Uc::Mqueue.new("#{queue_name}_prestart_#{i}")
|
38
|
-
mq.destroy
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def prestart_queue
|
43
|
-
first_worker? ? nil : "#{queue_name}_prestart_#{worker.nr - 1}"
|
44
|
-
end
|
45
|
-
|
46
|
-
def wait_for_prestart_end_event
|
47
|
-
return if not prestart_wait
|
48
|
-
if not prestart_queue
|
49
|
-
logger.debug "[rr] no ps wait for #{worker.nr + 1}"
|
50
|
-
return
|
51
|
-
end
|
52
|
-
begin
|
53
|
-
prestart_mq.create
|
54
|
-
msg = prestart_mq.wait( prestart_end_event, prestart_wait)
|
55
|
-
logger.debug "[rr] ps end event #{prestart_end_event} for #{ worker.nr + 1}"
|
56
|
-
rescue => e
|
57
|
-
logger.info "#{e.class} #{e.message}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def kill_old_worker
|
62
|
-
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
|
63
|
-
Process.kill(sig, File.read(old_pid).to_i)
|
64
|
-
mq_log "starting worker #{worker.nr + 1}"
|
65
|
-
mq_log "fin" if sig == :QUIT
|
66
|
-
rescue Errno::ENOENT, Errno::ESRCH, Errno::EAGAIN, Errno::EACCES => e
|
67
|
-
logger.error "rolling restart #{e.class} #{e.message}"
|
68
|
-
end
|
69
|
-
|
70
|
-
def prestart_end_event
|
71
|
-
run_id ? "prestart_end_#{run_id}" : "prestart_end"
|
72
|
-
end
|
73
|
-
|
74
|
-
def restart?
|
75
|
-
old_pid != server.pid
|
76
|
-
end
|
77
|
-
|
78
|
-
def first_worker?
|
79
|
-
worker.nr == 0
|
80
|
-
end
|
81
|
-
|
82
|
-
def old_pid
|
83
|
-
"#{server.config[:pid]}.oldbin"
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
end; end
|