unicorn 1.0.0 → 1.0.1
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.
- data/GIT-VERSION-GEN +1 -1
- data/lib/unicorn.rb +5 -0
- data/lib/unicorn/const.rb +2 -2
- data/lib/unicorn/launcher.rb +1 -5
- data/lib/unicorn/tee_input.rb +4 -3
- data/t/pid.ru +3 -0
- data/t/t0008-back_out_of_upgrade.sh +110 -0
- data/test/exec/test_exec.rb +17 -12
- metadata +6 -4
data/GIT-VERSION-GEN
CHANGED
data/lib/unicorn.rb
CHANGED
@@ -312,6 +312,11 @@ module Unicorn
|
|
312
312
|
if path
|
313
313
|
if x = valid_pid?(path)
|
314
314
|
return path if pid && path == pid && x == $$
|
315
|
+
if x == reexec_pid && pid =~ /\.oldbin\z/
|
316
|
+
logger.warn("will not set pid=#{path} while reexec-ed "\
|
317
|
+
"child is running PID:#{x}")
|
318
|
+
return
|
319
|
+
end
|
315
320
|
raise ArgumentError, "Already running on PID:#{x} " \
|
316
321
|
"(or pid=#{path} is stale)"
|
317
322
|
end
|
data/lib/unicorn/const.rb
CHANGED
@@ -8,8 +8,8 @@ module Unicorn
|
|
8
8
|
# Symbols did not really improve things much compared to constants.
|
9
9
|
module Const
|
10
10
|
|
11
|
-
# The current version of Unicorn, currently 1.0.
|
12
|
-
UNICORN_VERSION="1.0.
|
11
|
+
# The current version of Unicorn, currently 1.0.1
|
12
|
+
UNICORN_VERSION="1.0.1"
|
13
13
|
|
14
14
|
DEFAULT_HOST = "0.0.0.0" # default TCP listen host address
|
15
15
|
DEFAULT_PORT = 8080 # default TCP listen port
|
data/lib/unicorn/launcher.rb
CHANGED
@@ -24,11 +24,7 @@ module Unicorn::Launcher
|
|
24
24
|
|
25
25
|
# We only start a new process group if we're not being reexecuted
|
26
26
|
# and inheriting file descriptors from our parent
|
27
|
-
|
28
|
-
exit if fork
|
29
|
-
Process.setsid
|
30
|
-
exit if fork
|
31
|
-
else
|
27
|
+
unless ENV['UNICORN_FD']
|
32
28
|
# grandparent - reads pipe, exits when master is ready
|
33
29
|
# \_ parent - exits immediately ASAP
|
34
30
|
# \_ unicorn master - writes to pipe when ready
|
data/lib/unicorn/tee_input.rb
CHANGED
@@ -109,7 +109,7 @@ module Unicorn
|
|
109
109
|
# unlike IO#gets.
|
110
110
|
def gets
|
111
111
|
socket or return tmp.gets
|
112
|
-
|
112
|
+
sep = $/ or return read
|
113
113
|
|
114
114
|
orig_size = tmp.size
|
115
115
|
if tmp.pos == orig_size
|
@@ -117,8 +117,9 @@ module Unicorn
|
|
117
117
|
tmp.seek(orig_size)
|
118
118
|
end
|
119
119
|
|
120
|
+
sep_size = Rack::Utils.bytesize(sep)
|
120
121
|
line = tmp.gets # cannot be nil here since size > pos
|
121
|
-
|
122
|
+
sep == line[-sep_size, sep_size] and return line
|
122
123
|
|
123
124
|
# unlikely, if we got here, then tmp is at EOF
|
124
125
|
begin
|
@@ -126,7 +127,7 @@ module Unicorn
|
|
126
127
|
tee(Const::CHUNK_SIZE, buf2) or break
|
127
128
|
tmp.seek(orig_size)
|
128
129
|
line << tmp.gets
|
129
|
-
|
130
|
+
sep == line[-sep_size, sep_size] and return line
|
130
131
|
# tmp is at EOF again here, retry the loop
|
131
132
|
end while true
|
132
133
|
|
data/t/pid.ru
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
t_plan 13 "backout of USR2 upgrade"
|
4
|
+
|
5
|
+
worker_wait_start () {
|
6
|
+
test xSTART = x"$(cat $fifo)"
|
7
|
+
unicorn_pid=$(cat $pid)
|
8
|
+
}
|
9
|
+
|
10
|
+
t_begin "setup and start" && {
|
11
|
+
unicorn_setup
|
12
|
+
rm -f $pid.oldbin
|
13
|
+
|
14
|
+
cat >> $unicorn_config <<EOF
|
15
|
+
after_fork do |server, worker|
|
16
|
+
# test script will block while reading from $fifo,
|
17
|
+
# so notify the script on the first worker we spawn
|
18
|
+
# by opening the FIFO
|
19
|
+
if worker.nr == 0
|
20
|
+
File.open("$fifo", "wb") { |fp| fp.syswrite "START" }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
EOF
|
24
|
+
unicorn -D -c $unicorn_config pid.ru
|
25
|
+
worker_wait_start
|
26
|
+
orig_master_pid=$unicorn_pid
|
27
|
+
}
|
28
|
+
|
29
|
+
t_begin "read original worker pid" && {
|
30
|
+
orig_worker_pid=$(curl -sSf http://$listen/)
|
31
|
+
test -n "$orig_worker_pid" && kill -0 $orig_worker_pid
|
32
|
+
}
|
33
|
+
|
34
|
+
t_begin "upgrade to new master" && {
|
35
|
+
kill -USR2 $orig_master_pid
|
36
|
+
}
|
37
|
+
|
38
|
+
t_begin "kill old worker" && {
|
39
|
+
kill -WINCH $orig_master_pid
|
40
|
+
}
|
41
|
+
|
42
|
+
t_begin "wait for new worker to start" && {
|
43
|
+
worker_wait_start
|
44
|
+
test $unicorn_pid -ne $orig_master_pid
|
45
|
+
new_master_pid=$unicorn_pid
|
46
|
+
}
|
47
|
+
|
48
|
+
t_begin "old master pid is stashed in $pid.oldbin" && {
|
49
|
+
test -s "$pid.oldbin"
|
50
|
+
test $orig_master_pid -eq $(cat $pid.oldbin)
|
51
|
+
}
|
52
|
+
|
53
|
+
t_begin "ensure old worker is no longer running" && {
|
54
|
+
i=0
|
55
|
+
while kill -0 $orig_worker_pid 2>/dev/null
|
56
|
+
do
|
57
|
+
i=$(( $i + 1 ))
|
58
|
+
test $i -lt 600 || die "timed out"
|
59
|
+
sleep 1
|
60
|
+
done
|
61
|
+
}
|
62
|
+
|
63
|
+
t_begin "capture pid of new worker" && {
|
64
|
+
new_worker_pid=$(curl -sSf http://$listen/)
|
65
|
+
}
|
66
|
+
|
67
|
+
t_begin "reload old master process" && {
|
68
|
+
kill -HUP $orig_master_pid
|
69
|
+
worker_wait_start
|
70
|
+
}
|
71
|
+
|
72
|
+
t_begin "gracefully kill new master and ensure it dies" && {
|
73
|
+
kill -QUIT $new_master_pid
|
74
|
+
i=0
|
75
|
+
while kill -0 $new_worker_pid 2>/dev/null
|
76
|
+
do
|
77
|
+
i=$(( $i + 1 ))
|
78
|
+
test $i -lt 600 || die "timed out"
|
79
|
+
sleep 1
|
80
|
+
done
|
81
|
+
}
|
82
|
+
|
83
|
+
t_begin "ensure $pid.oldbin does not exist" && {
|
84
|
+
i=0
|
85
|
+
while test -s $pid.oldbin
|
86
|
+
do
|
87
|
+
i=$(( $i + 1 ))
|
88
|
+
test $i -lt 600 || die "timed out"
|
89
|
+
sleep 1
|
90
|
+
done
|
91
|
+
while ! test -s $pid
|
92
|
+
do
|
93
|
+
i=$(( $i + 1 ))
|
94
|
+
test $i -lt 600 || die "timed out"
|
95
|
+
sleep 1
|
96
|
+
done
|
97
|
+
}
|
98
|
+
|
99
|
+
t_begin "ensure $pid is correct" && {
|
100
|
+
cur_master_pid=$(cat $pid)
|
101
|
+
test $orig_master_pid -eq $cur_master_pid
|
102
|
+
}
|
103
|
+
|
104
|
+
t_begin "killing succeeds" && {
|
105
|
+
kill $orig_master_pid
|
106
|
+
}
|
107
|
+
|
108
|
+
dbgcat r_err
|
109
|
+
|
110
|
+
t_done
|
data/test/exec/test_exec.rb
CHANGED
@@ -54,6 +54,20 @@ before_fork do |server, worker|
|
|
54
54
|
end
|
55
55
|
EOS
|
56
56
|
|
57
|
+
WORKING_DIRECTORY_CHECK_RU = <<-EOS
|
58
|
+
use Rack::ContentLength
|
59
|
+
run lambda { |env|
|
60
|
+
pwd = ENV['PWD']
|
61
|
+
a = ::File.stat(pwd)
|
62
|
+
b = ::File.stat(Dir.pwd)
|
63
|
+
if (a.ino == b.ino && a.dev == b.dev)
|
64
|
+
[ 200, { 'Content-Type' => 'text/plain' }, [ pwd ] ]
|
65
|
+
else
|
66
|
+
[ 404, { 'Content-Type' => 'text/plain' }, [] ]
|
67
|
+
end
|
68
|
+
}
|
69
|
+
EOS
|
70
|
+
|
57
71
|
def setup
|
58
72
|
@pwd = Dir.pwd
|
59
73
|
@tmpfile = Tempfile.new('unicorn_exec_test')
|
@@ -87,10 +101,7 @@ end
|
|
87
101
|
File.unlink(other.path)
|
88
102
|
Dir.mkdir(other.path)
|
89
103
|
File.open("config.ru", "wb") do |fp|
|
90
|
-
fp.syswrite
|
91
|
-
use Rack::ContentLength
|
92
|
-
run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
|
93
|
-
EOF
|
104
|
+
fp.syswrite WORKING_DIRECTORY_CHECK_RU
|
94
105
|
end
|
95
106
|
FileUtils.cp("config.ru", other.path + "/config.ru")
|
96
107
|
Dir.chdir(@tmpdir)
|
@@ -138,10 +149,7 @@ EOF
|
|
138
149
|
File.unlink(other.path)
|
139
150
|
Dir.mkdir(other.path)
|
140
151
|
File.open("config.ru", "wb") do |fp|
|
141
|
-
fp.syswrite
|
142
|
-
use Rack::ContentLength
|
143
|
-
run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
|
144
|
-
EOF
|
152
|
+
fp.syswrite WORKING_DIRECTORY_CHECK_RU
|
145
153
|
end
|
146
154
|
FileUtils.cp("config.ru", other.path + "/config.ru")
|
147
155
|
tmp = Tempfile.new('unicorn.config')
|
@@ -177,10 +185,7 @@ EOF
|
|
177
185
|
File.unlink(other.path)
|
178
186
|
Dir.mkdir(other.path)
|
179
187
|
File.open("config.ru", "wb") do |fp|
|
180
|
-
fp.syswrite
|
181
|
-
use Rack::ContentLength
|
182
|
-
run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
|
183
|
-
EOF
|
188
|
+
fp.syswrite WORKING_DIRECTORY_CHECK_RU
|
184
189
|
end
|
185
190
|
FileUtils.cp("config.ru", other.path + "/config.ru")
|
186
191
|
system('mkfifo', "#{other.path}/fifo")
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Unicorn hackers
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-07-13 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -169,6 +169,7 @@ files:
|
|
169
169
|
- t/bin/utee
|
170
170
|
- t/env.ru
|
171
171
|
- t/my-tap-lib.sh
|
172
|
+
- t/pid.ru
|
172
173
|
- t/rails3-app/.gitignore
|
173
174
|
- t/rails3-app/Gemfile
|
174
175
|
- t/rails3-app/Rakefile
|
@@ -209,6 +210,7 @@ files:
|
|
209
210
|
- t/t0006-reopen-logs.sh
|
210
211
|
- t/t0006.ru
|
211
212
|
- t/t0007-working_directory_no_embed_cli.sh
|
213
|
+
- t/t0008-back_out_of_upgrade.sh
|
212
214
|
- t/t0300-rails3-basic.sh
|
213
215
|
- t/t0301-rails3-missing-config-ru.sh
|
214
216
|
- t/t0302-rails3-alt-working_directory.sh
|