unicorn 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Documentation/unicorn.1.txt +3 -0
- data/Documentation/unicorn_rails.1.txt +5 -2
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +2 -2
- data/Rakefile +3 -7
- data/ext/unicorn_http/unicorn_http.rl +1 -1
- data/lib/unicorn.rb +10 -13
- data/lib/unicorn/configurator.rb +466 -443
- data/lib/unicorn/const.rb +2 -2
- data/lib/unicorn/http_request.rb +1 -2
- data/lib/unicorn/http_response.rb +55 -60
- data/lib/unicorn/launcher.rb +5 -1
- data/lib/unicorn/socket_helper.rb +42 -24
- data/lib/unicorn/tee_input.rb +203 -195
- data/test/test_helper.rb +0 -1
- data/test/unit/test_socket_helper.rb +24 -0
- data/unicorn.gemspec +2 -2
- metadata +8 -11
- data/t/pid.ru +0 -3
- data/t/t0008-back_out_of_upgrade.sh +0 -110
- data/t/t0009-winch_ttin.sh +0 -59
- data/t/t0012-reload-empty-config.sh +0 -82
data/test/test_helper.rb
CHANGED
@@ -146,4 +146,28 @@ class TestSocketHelper < Test::Unit::TestCase
|
|
146
146
|
sock_name(@unix_server)
|
147
147
|
end
|
148
148
|
|
149
|
+
def test_tcp_defer_accept_default
|
150
|
+
port = unused_port @test_addr
|
151
|
+
name = "#@test_addr:#{port}"
|
152
|
+
sock = bind_listen(name)
|
153
|
+
cur = sock.getsockopt(Socket::SOL_TCP, TCP_DEFER_ACCEPT).unpack('i')[0]
|
154
|
+
assert cur >= 1
|
155
|
+
end if defined?(TCP_DEFER_ACCEPT)
|
156
|
+
|
157
|
+
def test_tcp_defer_accept_disable
|
158
|
+
port = unused_port @test_addr
|
159
|
+
name = "#@test_addr:#{port}"
|
160
|
+
sock = bind_listen(name, :tcp_defer_accept => false)
|
161
|
+
cur = sock.getsockopt(Socket::SOL_TCP, TCP_DEFER_ACCEPT).unpack('i')[0]
|
162
|
+
assert_equal 0, cur
|
163
|
+
end if defined?(TCP_DEFER_ACCEPT)
|
164
|
+
|
165
|
+
def test_tcp_defer_accept_nr
|
166
|
+
port = unused_port @test_addr
|
167
|
+
name = "#@test_addr:#{port}"
|
168
|
+
sock = bind_listen(name, :tcp_defer_accept => 60)
|
169
|
+
cur = sock.getsockopt(Socket::SOL_TCP, TCP_DEFER_ACCEPT).unpack('i')[0]
|
170
|
+
assert cur > 1
|
171
|
+
end if defined?(TCP_DEFER_ACCEPT)
|
172
|
+
|
149
173
|
end
|
data/unicorn.gemspec
CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
s.homepage = %q{http://unicorn.bogomips.org/}
|
37
37
|
|
38
38
|
summary = %q{Rack HTTP server for fast clients and Unix}
|
39
|
-
s.rdoc_options = [ "-t", "Unicorn: #{summary}" ]
|
39
|
+
s.rdoc_options = [ "-Na", "-t", "Unicorn: #{summary}" ]
|
40
40
|
s.require_paths = %w(lib ext)
|
41
41
|
s.rubyforge_project = %q{mongrel}
|
42
42
|
s.summary = summary
|
@@ -49,7 +49,7 @@ Gem::Specification.new do |s|
|
|
49
49
|
# *strongly* recommended for security reasons.
|
50
50
|
s.add_dependency(%q<rack>)
|
51
51
|
|
52
|
-
s.add_development_dependency('isolate', '~>
|
52
|
+
s.add_development_dependency('isolate', '~> 2.0.2')
|
53
53
|
|
54
54
|
# s.licenses = %w(GPLv2 Ruby) # licenses= method is not in older RubyGems
|
55
55
|
end
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.2
|
10
|
+
version: 1.1.0
|
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-08 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -40,12 +40,12 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
hash:
|
43
|
+
hash: 11
|
44
44
|
segments:
|
45
|
-
-
|
46
|
-
- 0
|
45
|
+
- 2
|
47
46
|
- 0
|
48
|
-
|
47
|
+
- 2
|
48
|
+
version: 2.0.2
|
49
49
|
type: :development
|
50
50
|
version_requirements: *id002
|
51
51
|
description: |-
|
@@ -169,7 +169,6 @@ files:
|
|
169
169
|
- t/bin/utee
|
170
170
|
- t/env.ru
|
171
171
|
- t/my-tap-lib.sh
|
172
|
-
- t/pid.ru
|
173
172
|
- t/rails3-app/.gitignore
|
174
173
|
- t/rails3-app/Gemfile
|
175
174
|
- t/rails3-app/Rakefile
|
@@ -210,9 +209,6 @@ files:
|
|
210
209
|
- t/t0006-reopen-logs.sh
|
211
210
|
- t/t0006.ru
|
212
211
|
- t/t0007-working_directory_no_embed_cli.sh
|
213
|
-
- t/t0008-back_out_of_upgrade.sh
|
214
|
-
- t/t0009-winch_ttin.sh
|
215
|
-
- t/t0012-reload-empty-config.sh
|
216
212
|
- t/t0300-rails3-basic.sh
|
217
213
|
- t/t0301-rails3-missing-config-ru.sh
|
218
214
|
- t/t0302-rails3-alt-working_directory.sh
|
@@ -321,6 +317,7 @@ licenses: []
|
|
321
317
|
|
322
318
|
post_install_message:
|
323
319
|
rdoc_options:
|
320
|
+
- -Na
|
324
321
|
- -t
|
325
322
|
- "Unicorn: Rack HTTP server for fast clients and Unix"
|
326
323
|
require_paths:
|
data/t/pid.ru
DELETED
@@ -1,110 +0,0 @@
|
|
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/t/t0009-winch_ttin.sh
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
. ./test-lib.sh
|
3
|
-
t_plan 8 "SIGTTIN succeeds after SIGWINCH"
|
4
|
-
|
5
|
-
t_begin "setup and start" && {
|
6
|
-
unicorn_setup
|
7
|
-
cat >> $unicorn_config <<EOF
|
8
|
-
after_fork do |server, worker|
|
9
|
-
# test script will block while reading from $fifo,
|
10
|
-
File.open("$fifo", "wb") { |fp| fp.syswrite worker.nr.to_s }
|
11
|
-
end
|
12
|
-
EOF
|
13
|
-
unicorn -D -c $unicorn_config pid.ru
|
14
|
-
unicorn_wait_start
|
15
|
-
test 0 -eq $(cat $fifo) || die "worker.nr != 0"
|
16
|
-
}
|
17
|
-
|
18
|
-
t_begin "read worker pid" && {
|
19
|
-
orig_worker_pid=$(curl -sSf http://$listen/)
|
20
|
-
test -n "$orig_worker_pid" && kill -0 $orig_worker_pid
|
21
|
-
}
|
22
|
-
|
23
|
-
t_begin "stop all workers" && {
|
24
|
-
kill -WINCH $unicorn_pid
|
25
|
-
}
|
26
|
-
|
27
|
-
# we have to do this next step before delivering TTIN
|
28
|
-
# signals aren't guaranteed to delivered in order
|
29
|
-
t_begin "wait for worker to die" && {
|
30
|
-
i=0
|
31
|
-
while kill -0 $orig_worker_pid 2>/dev/null
|
32
|
-
do
|
33
|
-
i=$(( $i + 1 ))
|
34
|
-
test $i -lt 600 || die "timed out"
|
35
|
-
sleep 1
|
36
|
-
done
|
37
|
-
}
|
38
|
-
|
39
|
-
t_begin "start one worker back up" && {
|
40
|
-
kill -TTIN $unicorn_pid
|
41
|
-
}
|
42
|
-
|
43
|
-
t_begin "wait for new worker to start" && {
|
44
|
-
test 0 -eq $(cat $fifo) || die "worker.nr != 0"
|
45
|
-
new_worker_pid=$(curl -sSf http://$listen/)
|
46
|
-
test -n "$new_worker_pid" && kill -0 $new_worker_pid
|
47
|
-
test $orig_worker_pid -ne $new_worker_pid || \
|
48
|
-
die "worker wasn't replaced"
|
49
|
-
}
|
50
|
-
|
51
|
-
t_begin "killing succeeds" && {
|
52
|
-
kill $unicorn_pid
|
53
|
-
}
|
54
|
-
|
55
|
-
t_begin "check stderr" && check_stderr
|
56
|
-
|
57
|
-
dbgcat r_err
|
58
|
-
|
59
|
-
t_done
|
@@ -1,82 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
. ./test-lib.sh
|
3
|
-
t_plan 9 "reloading unset config resets defaults"
|
4
|
-
|
5
|
-
t_begin "setup and start" && {
|
6
|
-
unicorn_setup
|
7
|
-
rtmpfiles unicorn_config_orig before_reload after_reload
|
8
|
-
cat $unicorn_config > $unicorn_config_orig
|
9
|
-
cat >> $unicorn_config <<EOF
|
10
|
-
logger Logger.new(STDOUT)
|
11
|
-
preload_app true
|
12
|
-
timeout 0x7fffffff
|
13
|
-
worker_processes 2
|
14
|
-
after_fork { |s,w| }
|
15
|
-
\$dump_cfg = lambda { |fp,srv|
|
16
|
-
defaults = Unicorn::Configurator::DEFAULTS
|
17
|
-
defaults.keys.map { |x| x.to_s }.sort.each do |key|
|
18
|
-
next if key =~ %r{\Astd(?:err|out)_path\z}
|
19
|
-
key = key.to_sym
|
20
|
-
def_value = defaults[key]
|
21
|
-
srv_value = srv.__send__(key)
|
22
|
-
fp << "#{key}|#{srv_value}|#{def_value}\\n"
|
23
|
-
end
|
24
|
-
}
|
25
|
-
before_fork { |s,w|
|
26
|
-
File.open("$before_reload", "a") { |fp| \$dump_cfg.call(fp, s) }
|
27
|
-
}
|
28
|
-
before_exec { |s| }
|
29
|
-
EOF
|
30
|
-
unicorn -D -c $unicorn_config env.ru
|
31
|
-
unicorn_wait_start
|
32
|
-
}
|
33
|
-
|
34
|
-
t_begin "ensure worker is started" && {
|
35
|
-
curl -sSf http://$listen/ > $tmp
|
36
|
-
}
|
37
|
-
|
38
|
-
t_begin "replace config file with original(-ish)" && {
|
39
|
-
grep -v ^pid < $unicorn_config_orig > $unicorn_config
|
40
|
-
cat >> $unicorn_config <<EOF
|
41
|
-
before_fork { |s,w|
|
42
|
-
File.open("$after_reload", "a") { |fp| \$dump_cfg.call(fp, s) }
|
43
|
-
}
|
44
|
-
EOF
|
45
|
-
}
|
46
|
-
|
47
|
-
t_begin "reload signal succeeds" && {
|
48
|
-
kill -HUP $unicorn_pid
|
49
|
-
while ! egrep '(done|error) reloading' $r_err >/dev/null
|
50
|
-
do
|
51
|
-
sleep 1
|
52
|
-
done
|
53
|
-
|
54
|
-
grep 'done reloading' $r_err >/dev/null
|
55
|
-
}
|
56
|
-
|
57
|
-
t_begin "ensure worker is started" && {
|
58
|
-
curl -sSf http://$listen/ > $tmp
|
59
|
-
}
|
60
|
-
|
61
|
-
t_begin "pid file no longer exists" && {
|
62
|
-
if test -f $pid
|
63
|
-
then
|
64
|
-
die "pid=$pid should not exist"
|
65
|
-
fi
|
66
|
-
}
|
67
|
-
|
68
|
-
t_begin "killing succeeds" && {
|
69
|
-
kill $unicorn_pid
|
70
|
-
}
|
71
|
-
|
72
|
-
t_begin "check stderr" && {
|
73
|
-
check_stderr
|
74
|
-
}
|
75
|
-
|
76
|
-
t_begin "ensure reloading restored settings" && {
|
77
|
-
awk < $after_reload -F'|' '
|
78
|
-
$1 != "before_fork" && $2 != $3 { print $0; exit(1) }
|
79
|
-
'
|
80
|
-
}
|
81
|
-
|
82
|
-
t_done
|