rainbows 5.0.0.5.ge717 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/GIT-VERSION-GEN +1 -1
- data/README +9 -0
- data/SIGNALS +3 -3
- data/lib/rainbows/configurator.rb +5 -0
- data/lib/rainbows/event_machine.rb +9 -1
- data/t/GNUmakefile +1 -1
- data/t/app_deferred.ru +7 -1
- data/t/t0044-autopush.sh +121 -0
- data/t/t0700-app-deferred.sh +15 -3
- data/t/test_isolate.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8cc2123c4d83730d582b5f321357fd6137ef00c
|
4
|
+
data.tar.gz: 10d4985653c1dd1d67a69e4947da5ea53044b08c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 274906c5e42e82a6ee566776a8a9a2c488cf9c1dca38a415a35355062b02b156bedbe1c617b36bce4264a28ed5cc166867ccb9a3403a61172ef639eab5de06b1
|
7
|
+
data.tar.gz: 16f81b05cdf620fe65ffe76dd266132e89856ccbf45c6f9748e75f2dc45e8e03afc3e586edfc01fbd6ded9d794348b06c5c71126f5dd38e003c6161e77bcd1f1
|
data/GIT-VERSION-GEN
CHANGED
data/README
CHANGED
@@ -159,6 +159,15 @@ don't email the git mailing list or maintainer with \Rainbows! patches.
|
|
159
159
|
There is NO WARRANTY whatsoever if anything goes wrong, but let us know
|
160
160
|
and we'll try our best to fix it.
|
161
161
|
|
162
|
+
Rainbows! is extremely sensitive to fatal bugs in the apps it hosts.
|
163
|
+
Each Rainbows! worker process may be handling thousands of clients;
|
164
|
+
unexpectedly killing the process will abort _all_ of those
|
165
|
+
connections. Lives may be lost!
|
166
|
+
|
167
|
+
Rainbows! hackers are not responsible for your application/library bugs.
|
168
|
+
Use an application server which is tolerant of buggy applications
|
169
|
+
if you cannot be bothered to fix all your fatal bugs.
|
170
|
+
|
162
171
|
== Contact
|
163
172
|
|
164
173
|
All feedback (bug reports, user/development discussion, patches, pull
|
data/SIGNALS
CHANGED
@@ -24,9 +24,9 @@ between \Rainbows!, unicorn and nginx.
|
|
24
24
|
* INT/TERM - quick shutdown, kills all workers immediately
|
25
25
|
|
26
26
|
* QUIT - graceful shutdown, waits for workers to finish their
|
27
|
-
current request before finishing.
|
28
|
-
|
29
|
-
EventMachine (
|
27
|
+
current request before finishing. Since Rainbows 5.1.0 (Jan 2017),
|
28
|
+
this waits requests deferred to a separate thread with
|
29
|
+
EventMachine (app.deferred?(env) => true).
|
30
30
|
|
31
31
|
* USR1 - reopen all logs owned by the master and all workers
|
32
32
|
See Unicorn::Util.reopen_logs for what is considered a log.
|
@@ -6,6 +6,11 @@
|
|
6
6
|
# block, otherwise Unicorn::Configurator directives may be used anywhere
|
7
7
|
# in the file.
|
8
8
|
#
|
9
|
+
# Warning: The "timeout" directive in unicorn is far more dangerous
|
10
|
+
# in Rainbows!, since ALL requests running on a process will be lost
|
11
|
+
# on worker death, not just one. Instead, handle application-level
|
12
|
+
# timeouts yourself: https://bogomips.org/unicorn/Application_Timeouts.html
|
13
|
+
#
|
9
14
|
# Rainbows! do
|
10
15
|
# use :ThreadSpawn # concurrency model to use
|
11
16
|
# worker_connections 400
|
@@ -65,6 +65,11 @@ def em_client_class
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
def defers_finished?
|
69
|
+
# EventMachine 1.0.0+ has defers_finished?
|
70
|
+
EM.respond_to?(:defers_finished?) ? EM.defers_finished? : true
|
71
|
+
end
|
72
|
+
|
68
73
|
# runs inside each forked worker, this sits around and waits
|
69
74
|
# for connections and doesn't die until the parent dies (or is
|
70
75
|
# given a INT, QUIT, or TERM signal)
|
@@ -101,7 +106,10 @@ def worker_loop(worker) # :nodoc:
|
|
101
106
|
end
|
102
107
|
end
|
103
108
|
EM.add_periodic_timer(1) do
|
104
|
-
|
109
|
+
if ! Rainbows.tick && conns.empty? && defers_finished? &&
|
110
|
+
EM.reactor_running?
|
111
|
+
EM.stop
|
112
|
+
end
|
105
113
|
end
|
106
114
|
LISTENERS.map! do |s|
|
107
115
|
EM.watch(s, Rainbows::EventMachine::Server) do |c|
|
data/t/GNUmakefile
CHANGED
@@ -41,6 +41,7 @@ ifeq ($(RUBY_ENGINE),ruby)
|
|
41
41
|
endif
|
42
42
|
models += FiberSpawn
|
43
43
|
models += FiberPool
|
44
|
+
models += EventMachine
|
44
45
|
|
45
46
|
RUBY_LE_2_1 := $(shell $(RUBY) -e 'puts(RUBY_VERSION.to_f <= 2.1)')
|
46
47
|
ifeq ($(RUBY_LE_2_1), true)
|
@@ -48,7 +49,6 @@ ifeq ($(RUBY_ENGINE),ruby)
|
|
48
49
|
models += CoolioThreadPool
|
49
50
|
models += CoolioThreadSpawn
|
50
51
|
models += CoolioFiberSpawn
|
51
|
-
models += EventMachine
|
52
52
|
models += NeverBlock
|
53
53
|
endif
|
54
54
|
endif
|
data/t/app_deferred.ru
CHANGED
@@ -6,12 +6,18 @@
|
|
6
6
|
|
7
7
|
class DeferredApp < Struct.new(:app)
|
8
8
|
def deferred?(env)
|
9
|
-
env["PATH_INFO"]
|
9
|
+
env["PATH_INFO"] =~ %r{\A/deferred}
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(env)
|
13
13
|
env["rack.multithread"] or raise RuntimeError, "rack.multithread not true"
|
14
14
|
body = "#{Thread.current.inspect}\n"
|
15
|
+
if env["PATH_INFO"] =~ %r{\A/deferred(\d+)}
|
16
|
+
delay = $1.to_i
|
17
|
+
File.open(ENV['fifo'], 'w') { |fp| fp.write "sleeping #{delay}s\n" }
|
18
|
+
body = "deferred sleep\n"
|
19
|
+
sleep(delay)
|
20
|
+
end
|
15
21
|
headers = {
|
16
22
|
"Content-Type" => "text/plain",
|
17
23
|
"Content-Length" => body.size.to_s,
|
data/t/t0044-autopush.sh
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
STRACE=$(which strace 2>/dev/null || :)
|
4
|
+
if ! test -x "$STRACE"
|
5
|
+
then
|
6
|
+
t_info "strace not found, skipping $T"
|
7
|
+
exit 0
|
8
|
+
fi
|
9
|
+
if test x"$(uname -s)" != xLinux
|
10
|
+
then
|
11
|
+
t_info "Linux is the only supported OS for $T"
|
12
|
+
exit 0
|
13
|
+
fi
|
14
|
+
|
15
|
+
# these buffer internally in external libraries, so we can't detect when
|
16
|
+
# to use TCP_CORK
|
17
|
+
skip_models EventMachine NeverBlock
|
18
|
+
skip_models StreamResponseEpoll
|
19
|
+
skip_models Coolio CoolioThreadPool CoolioThreadSpawn
|
20
|
+
skip_models Revactor Rev RevThreadPool RevThreadSpawn
|
21
|
+
|
22
|
+
# not sure why, but we don't have time to care about Ruby 1.8 too much
|
23
|
+
case $RUBY_VERSION in
|
24
|
+
1.8.*) skip_models WriterThreadSpawn WriterThreadPool ;;
|
25
|
+
esac
|
26
|
+
|
27
|
+
t_plan 13 "Kgio autopush tests"
|
28
|
+
|
29
|
+
start_strace () {
|
30
|
+
# dbgcat strace_out
|
31
|
+
> $strace_out
|
32
|
+
sleep 1
|
33
|
+
strace -p $worker_pid -e '!futex' -f -o $strace_out &
|
34
|
+
strace_pid=$!
|
35
|
+
while ! test -s $strace_out; do sleep 1; done
|
36
|
+
}
|
37
|
+
|
38
|
+
check_TCP_CORK () {
|
39
|
+
nr=0
|
40
|
+
while test 2 -gt $(grep TCP_CORK $strace_out | count_lines)
|
41
|
+
do
|
42
|
+
nr=$(( $nr + 1 ))
|
43
|
+
if test $nr -gt 30
|
44
|
+
then
|
45
|
+
dbgcat strace_out
|
46
|
+
die "waited too long ($nr seconds) for TCP_CORK"
|
47
|
+
fi
|
48
|
+
sleep 1
|
49
|
+
done
|
50
|
+
|
51
|
+
test 2 -eq $(grep TCP_CORK $strace_out | count_lines)
|
52
|
+
fgrep 'SOL_TCP, TCP_CORK, [0],' $strace_out
|
53
|
+
fgrep 'SOL_TCP, TCP_CORK, [1],' $strace_out
|
54
|
+
}
|
55
|
+
|
56
|
+
t_begin "setup and start" && {
|
57
|
+
rainbows_setup $model 1 1
|
58
|
+
rtmpfiles strace_out
|
59
|
+
ed -s $unicorn_config <<EOF
|
60
|
+
,s/^listen.*/listen "$listen", :tcp_nodelay => true, :tcp_nopush => true/
|
61
|
+
w
|
62
|
+
EOF
|
63
|
+
rainbows -D large-file-response.ru -c $unicorn_config -E none
|
64
|
+
rainbows_wait_start
|
65
|
+
}
|
66
|
+
|
67
|
+
t_begin "read worker pid" && {
|
68
|
+
worker_pid=$(curl -sSf http://$listen/pid)
|
69
|
+
kill -0 $worker_pid
|
70
|
+
}
|
71
|
+
|
72
|
+
t_begin "start strace on worker" && start_strace
|
73
|
+
|
74
|
+
t_begin "reading RSS uncorks" && {
|
75
|
+
curl -sSf http://$listen/rss >/dev/null
|
76
|
+
}
|
77
|
+
|
78
|
+
t_begin "restart strace on worker" && {
|
79
|
+
kill $strace_pid
|
80
|
+
wait
|
81
|
+
start_strace
|
82
|
+
}
|
83
|
+
|
84
|
+
t_begin "reading static file uncorks" && {
|
85
|
+
curl -sSf http://$listen/random_blob >/dev/null
|
86
|
+
check_TCP_CORK
|
87
|
+
}
|
88
|
+
|
89
|
+
t_begin "stop strace on worker" && {
|
90
|
+
kill $strace_pid
|
91
|
+
wait
|
92
|
+
}
|
93
|
+
|
94
|
+
t_begin "enable sendfile" && {
|
95
|
+
echo >> $unicorn_config 'require "sendfile"'
|
96
|
+
kill -HUP $rainbows_pid
|
97
|
+
test xSTART = x"$(cat $fifo)"
|
98
|
+
}
|
99
|
+
|
100
|
+
t_begin "reread worker pid" && {
|
101
|
+
worker_pid=$(curl -sSf http://$listen/pid)
|
102
|
+
kill -0 $worker_pid
|
103
|
+
}
|
104
|
+
|
105
|
+
t_begin "restart strace on the worker" && start_strace
|
106
|
+
|
107
|
+
t_begin "HTTP/1.x GET on static file with sendfile uncorks" && {
|
108
|
+
curl -sSf http://$listen/random_blob >/dev/null
|
109
|
+
check_TCP_CORK
|
110
|
+
}
|
111
|
+
|
112
|
+
t_begin "killing succeeds" && {
|
113
|
+
kill $strace_pid
|
114
|
+
wait
|
115
|
+
# dbgcat strace_out
|
116
|
+
kill $rainbows_pid
|
117
|
+
}
|
118
|
+
|
119
|
+
t_begin "check stderr" && check_stderr
|
120
|
+
|
121
|
+
t_done
|
data/t/t0700-app-deferred.sh
CHANGED
@@ -15,7 +15,7 @@ CONFIG_RU=app_deferred.ru
|
|
15
15
|
t_begin "setup and start" && {
|
16
16
|
rainbows_setup
|
17
17
|
rtmpfiles deferred_err deferred_out sync_err sync_out
|
18
|
-
rainbows -D -c $unicorn_config $CONFIG_RU
|
18
|
+
fifo=$fifo rainbows -D -c $unicorn_config $CONFIG_RU
|
19
19
|
rainbows_wait_start
|
20
20
|
}
|
21
21
|
|
@@ -36,8 +36,20 @@ t_begin "deferred requests run in a different thread" && {
|
|
36
36
|
test x"$(uniq < $deferred_out)" != x"$sync_thread"
|
37
37
|
}
|
38
38
|
|
39
|
-
t_begin "
|
40
|
-
|
39
|
+
t_begin "deferred requests run after graceful shutdown" && {
|
40
|
+
# XXX sleeping 5s ought to be enough for SIGQUIT to arrive,
|
41
|
+
# hard to tell with overloaded systems...
|
42
|
+
s=5
|
43
|
+
curl -sSf --no-buffer http://$listen/deferred$s \
|
44
|
+
>$deferred_out 2>$deferred_err &
|
45
|
+
curl_pid=$!
|
46
|
+
msg="$(cat $fifo)"
|
47
|
+
kill -QUIT $rainbows_pid
|
48
|
+
test x"$msg" = x"sleeping ${s}s"
|
49
|
+
wait $curl_pid # for curl to finish
|
50
|
+
test $? -eq 0
|
51
|
+
test ! -s $deferred_err
|
52
|
+
test x"$(cat $deferred_out)" = 'xdeferred sleep'
|
41
53
|
}
|
42
54
|
|
43
55
|
t_begin "no errors in stderr" && check_stderr
|
data/t/test_isolate.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rainbows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rainbows! hackers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -387,6 +387,7 @@ files:
|
|
387
387
|
- t/t0041-optional-pool-size.sh
|
388
388
|
- t/t0042-client_header_buffer_size.sh
|
389
389
|
- t/t0043-quit-keepalive-disconnect.sh
|
390
|
+
- t/t0044-autopush.sh
|
390
391
|
- t/t0045-client_max_header_size.sh
|
391
392
|
- t/t0050-response-body-close-has-env.sh
|
392
393
|
- t/t0100-rack-input-hammer-chunked.sh
|
@@ -447,12 +448,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
447
448
|
version: '0'
|
448
449
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
449
450
|
requirements:
|
450
|
-
- - "
|
451
|
+
- - ">="
|
451
452
|
- !ruby/object:Gem::Version
|
452
|
-
version:
|
453
|
+
version: '0'
|
453
454
|
requirements: []
|
454
455
|
rubyforge_project:
|
455
|
-
rubygems_version: 2.6.
|
456
|
+
rubygems_version: 2.6.8
|
456
457
|
signing_key:
|
457
458
|
specification_version: 4
|
458
459
|
summary: "- unicorn for sleepy apps and slow clients"
|