rainbows 3.3.0 → 3.4.0
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/.gitignore +2 -0
- data/GIT-VERSION-GEN +1 -1
- data/lib/rainbows/client.rb +2 -0
- data/lib/rainbows/configurator.rb +3 -1
- data/lib/rainbows/coolio/heartbeat.rb +1 -0
- data/lib/rainbows/epoll.rb +4 -21
- data/lib/rainbows/epoll/client.rb +17 -2
- data/lib/rainbows/epoll/response_pipe.rb +1 -1
- data/lib/rainbows/epoll/server.rb +7 -5
- data/lib/rainbows/event_machine.rb +5 -7
- data/lib/rainbows/event_machine/try_defer.rb +14 -9
- data/lib/rainbows/xepoll.rb +3 -4
- data/lib/rainbows/xepoll/client.rb +11 -4
- data/lib/rainbows/xepoll_thread_pool.rb +1 -1
- data/lib/rainbows/xepoll_thread_pool/client.rb +6 -2
- data/lib/rainbows/xepoll_thread_spawn.rb +1 -1
- data/lib/rainbows/xepoll_thread_spawn/client.rb +5 -1
- data/pkg.mk +2 -2
- data/t/large-file-response.ru +3 -0
- data/t/t0043-quit-keepalive-disconnect.sh +59 -0
- data/t/t0044-autopush.sh +120 -0
- data/t/test_isolate.rb +2 -2
- metadata +6 -4
data/.gitignore
CHANGED
data/GIT-VERSION-GEN
CHANGED
data/lib/rainbows/client.rb
CHANGED
@@ -190,7 +190,9 @@ module Rainbows::Configurator
|
|
190
190
|
# end
|
191
191
|
#
|
192
192
|
# Keep in mind that splice(2) itself is a relatively new system call
|
193
|
-
# and has been buggy in many older Linux kernels.
|
193
|
+
# and has been buggy in many older Linux kernels. If you're proxying
|
194
|
+
# the output of sockets to the client, be sure to use "io_splice"
|
195
|
+
# 4.1.1 or later to avoid stalling responses.
|
194
196
|
#
|
195
197
|
# Default: IO on Ruby 1.9+, false otherwise
|
196
198
|
def copy_stream(klass)
|
@@ -9,6 +9,7 @@ class Rainbows::Coolio::Heartbeat < Coolio::TimerWatcher
|
|
9
9
|
KATO = Rainbows::Coolio::KATO
|
10
10
|
CONN = Rainbows::Coolio::CONN
|
11
11
|
Rainbows.config!(self, :keepalive_timeout)
|
12
|
+
Rainbows.at_quit { KATO.each_key { |client| client.timeout? }.clear }
|
12
13
|
|
13
14
|
def on_timer
|
14
15
|
if (ot = KEEPALIVE_TIMEOUT) >= 0
|
data/lib/rainbows/epoll.rb
CHANGED
@@ -22,44 +22,27 @@ require 'sendfile'
|
|
22
22
|
# === RubyGem Requirements
|
23
23
|
#
|
24
24
|
# * raindrops 0.6.0 or later
|
25
|
-
# * sleepy_penguin
|
25
|
+
# * sleepy_penguin 3.0.1 or later
|
26
26
|
# * sendfile 1.1.0 or later
|
27
27
|
#
|
28
28
|
module Rainbows::Epoll
|
29
29
|
# :stopdoc:
|
30
30
|
include Rainbows::Base
|
31
|
-
ReRun = []
|
32
31
|
autoload :Server, 'rainbows/epoll/server'
|
33
32
|
autoload :Client, 'rainbows/epoll/client'
|
34
33
|
autoload :ResponsePipe, 'rainbows/epoll/response_pipe'
|
35
34
|
autoload :ResponseChunkPipe, 'rainbows/epoll/response_chunk_pipe'
|
36
|
-
class << self
|
37
|
-
attr_writer :nr_clients
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.loop
|
41
|
-
begin
|
42
|
-
EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
|
43
|
-
while obj = ReRun.shift
|
44
|
-
obj.epoll_run
|
45
|
-
end
|
46
|
-
Rainbows::Epoll::Client.expire
|
47
|
-
rescue Errno::EINTR
|
48
|
-
rescue => e
|
49
|
-
Rainbows::Error.listen_loop(e)
|
50
|
-
end while Rainbows.tick || @nr_clients.call > 0
|
51
|
-
end
|
52
35
|
|
53
36
|
def init_worker_process(worker)
|
54
37
|
super
|
55
|
-
Rainbows
|
56
|
-
Rainbows.at_quit { Rainbows::Epoll::EP.close }
|
38
|
+
Rainbows.const_set(:EP, SleepyPenguin::Epoll.new)
|
57
39
|
Rainbows::Client.__send__ :include, Client
|
40
|
+
LISTENERS.each { |io| io.extend(Server) }
|
58
41
|
end
|
59
42
|
|
60
43
|
def worker_loop(worker) # :nodoc:
|
61
44
|
init_worker_process(worker)
|
62
|
-
|
45
|
+
Client.loop
|
63
46
|
end
|
64
47
|
# :startdoc:
|
65
48
|
end
|
@@ -10,8 +10,10 @@ module Rainbows::Epoll::Client
|
|
10
10
|
OUT = SleepyPenguin::Epoll::OUT | SleepyPenguin::Epoll::ET
|
11
11
|
KATO = {}
|
12
12
|
KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
|
13
|
+
Rainbows.at_quit { KATO.each_key { |k| k.timeout! }.clear }
|
13
14
|
Rainbows.config!(self, :keepalive_timeout)
|
14
|
-
EP = Rainbows::
|
15
|
+
EP = Rainbows::EP
|
16
|
+
ReRun = []
|
15
17
|
@@last_expire = Time.now
|
16
18
|
|
17
19
|
def self.expire
|
@@ -23,6 +25,19 @@ module Rainbows::Epoll::Client
|
|
23
25
|
@@last_expire = now
|
24
26
|
end
|
25
27
|
|
28
|
+
def self.loop
|
29
|
+
begin
|
30
|
+
EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
|
31
|
+
while obj = ReRun.shift
|
32
|
+
obj.epoll_run
|
33
|
+
end
|
34
|
+
expire
|
35
|
+
rescue Errno::EINTR
|
36
|
+
rescue => e
|
37
|
+
Rainbows::Error.listen_loop(e)
|
38
|
+
end while Rainbows.tick || Server.nr > 0
|
39
|
+
end
|
40
|
+
|
26
41
|
# only call this once
|
27
42
|
def epoll_once
|
28
43
|
@wr_queue = [] # may contain String, ResponsePipe, and StreamFile objects
|
@@ -100,7 +115,7 @@ module Rainbows::Epoll::Client
|
|
100
115
|
end
|
101
116
|
|
102
117
|
def want_more
|
103
|
-
|
118
|
+
ReRun << self
|
104
119
|
end
|
105
120
|
|
106
121
|
def on_deferred_write_complete
|
@@ -2,16 +2,14 @@
|
|
2
2
|
# :enddoc:
|
3
3
|
module Rainbows::Epoll::Server
|
4
4
|
@@nr = 0
|
5
|
-
Rainbows::Epoll.nr_clients = lambda { @@nr }
|
6
5
|
IN = SleepyPenguin::Epoll::IN | SleepyPenguin::Epoll::ET
|
7
6
|
MAX = Rainbows.server.worker_connections
|
8
7
|
THRESH = MAX - 1
|
9
8
|
LISTENERS = Rainbows::HttpServer::LISTENERS
|
10
|
-
EP = Rainbows::
|
9
|
+
EP = Rainbows::EP
|
11
10
|
|
12
|
-
def self.
|
13
|
-
|
14
|
-
Rainbows::Epoll.loop
|
11
|
+
def self.nr
|
12
|
+
@@nr
|
15
13
|
end
|
16
14
|
|
17
15
|
# rearms all listeners when there's a free slot
|
@@ -19,6 +17,10 @@ module Rainbows::Epoll::Server
|
|
19
17
|
THRESH == (@@nr -= 1) and LISTENERS.each { |sock| EP.set(sock, IN) }
|
20
18
|
end
|
21
19
|
|
20
|
+
def self.extended(sock)
|
21
|
+
EP.set(sock, IN)
|
22
|
+
end
|
23
|
+
|
22
24
|
def epoll_run
|
23
25
|
return EP.delete(self) if @@nr >= MAX
|
24
26
|
while io = kgio_tryaccept
|
@@ -32,9 +32,7 @@ EM::VERSION >= '0.12.10' or abort 'eventmachine 0.12.10 is required'
|
|
32
32
|
# all request processing is complete.
|
33
33
|
#
|
34
34
|
# Merb (and other frameworks/apps) supporting +deferred?+ execution as
|
35
|
-
# documented at
|
36
|
-
# will also get the ability to conditionally defer request processing
|
37
|
-
# to a separate thread.
|
35
|
+
# documented at Rainbows::EventMachine::TryDefer
|
38
36
|
#
|
39
37
|
# This model does not implement as streaming "rack.input" which allows
|
40
38
|
# the Rack application to process data as it arrives. This means
|
@@ -74,11 +72,11 @@ module Rainbows::EventMachine
|
|
74
72
|
conns = EM.instance_variable_get(:@conns) or
|
75
73
|
raise RuntimeError, "EM @conns instance variable not accessible!"
|
76
74
|
Rainbows::EventMachine::Server.const_set(:CUR, conns)
|
75
|
+
Rainbows.at_quit do
|
76
|
+
EM.next_tick { conns.each_value { |c| client_class === c and c.quit } }
|
77
|
+
end
|
77
78
|
EM.add_periodic_timer(1) do
|
78
|
-
|
79
|
-
conns.each_value { |c| client_class === c and c.quit }
|
80
|
-
EM.stop if conns.empty? && EM.reactor_running?
|
81
|
-
end
|
79
|
+
EM.stop if ! Rainbows.tick && conns.empty? && EM.reactor_running?
|
82
80
|
end
|
83
81
|
LISTENERS.map! do |s|
|
84
82
|
EM.watch(s, Rainbows::EventMachine::Server) do |c|
|
@@ -1,27 +1,32 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
|
-
# :enddoc:
|
3
2
|
|
4
3
|
# Middleware that will run the app dispatch in a separate thread.
|
5
4
|
# This middleware is automatically loaded by Rainbows! when using
|
6
5
|
# EventMachine and if the app responds to the +deferred?+ method.
|
7
|
-
|
6
|
+
#
|
7
|
+
# Use EM.threadpool_size in your \Rainbows! config file to control
|
8
|
+
# the number of threads used by EventMachine.
|
9
|
+
#
|
10
|
+
# See http://brainspl.at/articles/2008/04/18/deferred-requests-with-merb-ebb-and-thin
|
11
|
+
# for more information.
|
12
|
+
class Rainbows::EventMachine::TryDefer
|
8
13
|
# shortcuts
|
9
|
-
ASYNC_CALLBACK = Rainbows::EvCore::ASYNC_CALLBACK
|
14
|
+
ASYNC_CALLBACK = Rainbows::EvCore::ASYNC_CALLBACK # :nodoc:
|
10
15
|
|
11
|
-
def initialize(app)
|
16
|
+
def initialize(app) # :nodoc:
|
12
17
|
# the entire app becomes multithreaded, even the root (non-deferred)
|
13
18
|
# thread since any thread can share processes with others
|
14
19
|
Rainbows::Const::RACK_DEFAULTS['rack.multithread'] = true
|
15
|
-
|
20
|
+
@app = app
|
16
21
|
end
|
17
22
|
|
18
|
-
def call(env)
|
19
|
-
if app.deferred?(env)
|
20
|
-
EM.defer(proc { catch(:async) { app.call(env) } }, env[ASYNC_CALLBACK])
|
23
|
+
def call(env) # :nodoc:
|
24
|
+
if @app.deferred?(env)
|
25
|
+
EM.defer(proc { catch(:async) { @app.call(env) } }, env[ASYNC_CALLBACK])
|
21
26
|
# all of the async/deferred stuff breaks Rack::Lint :<
|
22
27
|
nil
|
23
28
|
else
|
24
|
-
app.call(env)
|
29
|
+
@app.call(env)
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
data/lib/rainbows/xepoll.rb
CHANGED
@@ -10,7 +10,7 @@ require 'rainbows/epoll'
|
|
10
10
|
# === RubyGem Requirements
|
11
11
|
#
|
12
12
|
# * raindrops 0.6.0 or later
|
13
|
-
# * sleepy_penguin
|
13
|
+
# * sleepy_penguin 3.0.1 or later
|
14
14
|
# * sendfile 1.1.0 or later
|
15
15
|
module Rainbows::XEpoll
|
16
16
|
# :stopdoc:
|
@@ -19,14 +19,13 @@ module Rainbows::XEpoll
|
|
19
19
|
|
20
20
|
def init_worker_process(worker)
|
21
21
|
super
|
22
|
-
Rainbows
|
23
|
-
Rainbows.at_quit { Rainbows::Epoll::EP.close }
|
22
|
+
Rainbows.const_set(:EP, SleepyPenguin::Epoll.new)
|
24
23
|
Rainbows::Client.__send__ :include, Client
|
25
24
|
end
|
26
25
|
|
27
26
|
def worker_loop(worker) # :nodoc:
|
28
27
|
init_worker_process(worker)
|
29
|
-
Client.
|
28
|
+
Client.loop
|
30
29
|
end
|
31
30
|
# :startdoc:
|
32
31
|
end
|
@@ -3,9 +3,7 @@
|
|
3
3
|
|
4
4
|
module Rainbows::XEpoll::Client
|
5
5
|
N = Raindrops.new(1)
|
6
|
-
Rainbows::Epoll.nr_clients = lambda { N[0] }
|
7
6
|
include Rainbows::Epoll::Client
|
8
|
-
EP = Rainbows::Epoll::EP
|
9
7
|
ACCEPTORS = Rainbows::HttpServer::LISTENERS.dup
|
10
8
|
extend Rainbows::WorkerYield
|
11
9
|
|
@@ -26,8 +24,17 @@ module Rainbows::XEpoll::Client
|
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
def self.
|
30
|
-
|
27
|
+
def self.loop
|
28
|
+
begin
|
29
|
+
EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
|
30
|
+
while obj = ReRun.shift
|
31
|
+
obj.epoll_run
|
32
|
+
end
|
33
|
+
Rainbows::Epoll::Client.expire
|
34
|
+
rescue Errno::EINTR
|
35
|
+
rescue => e
|
36
|
+
Rainbows::Error.listen_loop(e)
|
37
|
+
end while Rainbows.tick || N[0] > 0
|
31
38
|
Rainbows::JoinThreads.acceptors(ACCEPTORS)
|
32
39
|
end
|
33
40
|
|
@@ -37,11 +37,15 @@ module Rainbows::XEpollThreadPool::Client
|
|
37
37
|
|
38
38
|
ep = SleepyPenguin::Epoll
|
39
39
|
EP = ep.new
|
40
|
-
Rainbows.at_quit { EP.close }
|
41
40
|
IN = ep::IN | ep::ET | ep::ONESHOT
|
42
41
|
KATO = {}
|
43
42
|
KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
|
44
43
|
LOCK = Mutex.new
|
44
|
+
Rainbows.at_quit do
|
45
|
+
clients = nil
|
46
|
+
LOCK.synchronize { clients = KATO.keys; KATO.clear }
|
47
|
+
clients.each { |io| io.closed? or io.close }
|
48
|
+
end
|
45
49
|
@@last_expire = Time.now
|
46
50
|
|
47
51
|
def kato_set
|
@@ -123,7 +127,7 @@ module Rainbows::XEpollThreadPool::Client
|
|
123
127
|
def pipeline_ready(hp)
|
124
128
|
# be fair to other clients, let others run first
|
125
129
|
hp.parse and return queue!
|
126
|
-
|
130
|
+
epoll_run("")
|
127
131
|
false
|
128
132
|
end
|
129
133
|
end
|
@@ -26,11 +26,15 @@ module Rainbows::XEpollThreadSpawn::Client
|
|
26
26
|
|
27
27
|
ep = SleepyPenguin::Epoll
|
28
28
|
EP = ep.new
|
29
|
-
Rainbows.at_quit { EP.close }
|
30
29
|
IN = ep::IN | ep::ET | ep::ONESHOT
|
31
30
|
KATO = {}
|
32
31
|
KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
|
33
32
|
LOCK = Mutex.new
|
33
|
+
Rainbows.at_quit do
|
34
|
+
clients = nil
|
35
|
+
LOCK.synchronize { clients = KATO.keys; KATO.clear }
|
36
|
+
clients.each { |io| io.closed? or io.close }
|
37
|
+
end
|
34
38
|
@@last_expire = Time.now
|
35
39
|
|
36
40
|
def kato_set
|
data/pkg.mk
CHANGED
@@ -69,7 +69,7 @@ doc:: .document .wrongdoc.yml $(pkg_extra)
|
|
69
69
|
$(RM) -r doc
|
70
70
|
$(WRONGDOC) all
|
71
71
|
install -m644 COPYING doc/COPYING
|
72
|
-
install -m644 $(shell grep '^[A-Z]' .document) doc/
|
72
|
+
install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
|
73
73
|
|
74
74
|
ifneq ($(VERSION),)
|
75
75
|
pkggem := pkg/$(rfpackage)-$(VERSION).gem
|
@@ -168,7 +168,7 @@ doc_gz:
|
|
168
168
|
for i in $(docs); do \
|
169
169
|
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
170
170
|
check-warnings:
|
171
|
-
@(for i in $$(git ls-files '*.rb'|grep -v '^setup\.rb$$'); \
|
171
|
+
@(for i in $$(git ls-files '*.rb'| grep -v '^setup\.rb$$'); \
|
172
172
|
do $(RUBY) -d -W2 -c $$i; done) | grep -v '^Syntax OK$$' || :
|
173
173
|
|
174
174
|
.PHONY: all .FORCE-GIT-VERSION-FILE doc test $(test_units) manifest
|
data/t/large-file-response.ru
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
case $model in
|
4
|
+
Coolio|CoolioThreadSpawn|CoolioThreadPool|EventMachine) ;;
|
5
|
+
Epoll|XEpoll|XEpollThreadPool|XEpollThreadSpawn) ;;
|
6
|
+
*)
|
7
|
+
t_info "$0 not supported for $model"
|
8
|
+
exit 0
|
9
|
+
;;
|
10
|
+
esac
|
11
|
+
|
12
|
+
t_plan 7 "keepalive clients disconnected on SIGQUIT for $model"
|
13
|
+
|
14
|
+
t_begin "setup and start" && {
|
15
|
+
rainbows_setup $model 50 30
|
16
|
+
rainbows -E none -D env.ru -c $unicorn_config
|
17
|
+
rainbows_wait_start
|
18
|
+
}
|
19
|
+
|
20
|
+
t_begin "start a keepalive request" && {
|
21
|
+
(
|
22
|
+
cat < $fifo > $tmp &
|
23
|
+
printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'
|
24
|
+
wait
|
25
|
+
) | socat - TCP4:$listen > $fifo &
|
26
|
+
}
|
27
|
+
|
28
|
+
t_begin "wait for response" && {
|
29
|
+
while ! tail -1 < $tmp | grep '}$' >/dev/null
|
30
|
+
do
|
31
|
+
sleep 1
|
32
|
+
done
|
33
|
+
}
|
34
|
+
|
35
|
+
t_begin "stop Rainbows! gracefully" && {
|
36
|
+
t0=$(date +%s)
|
37
|
+
kill -QUIT $rainbows_pid
|
38
|
+
}
|
39
|
+
|
40
|
+
t_begin "keepalive client disconnected quickly" && {
|
41
|
+
wait
|
42
|
+
diff=$(( $(date +%s) - $t0 ))
|
43
|
+
test $diff -le 2 || die "client diff=$diff > 2"
|
44
|
+
}
|
45
|
+
|
46
|
+
t_begin "wait for termination" && {
|
47
|
+
while kill -0 $rainbows_pid
|
48
|
+
do
|
49
|
+
sleep 1
|
50
|
+
done
|
51
|
+
diff=$(( $(date +%s) - $t0 ))
|
52
|
+
test $diff -le 4 || die "server diff=$diff > 4"
|
53
|
+
}
|
54
|
+
|
55
|
+
t_begin "check stderr" && {
|
56
|
+
check_stderr
|
57
|
+
}
|
58
|
+
|
59
|
+
t_done
|
data/t/t0044-autopush.sh
ADDED
@@ -0,0 +1,120 @@
|
|
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 Coolio CoolioThreadPool CoolioThreadSpawn
|
19
|
+
skip_models Revactor Rev RevThreadPool RevThreadSpawn
|
20
|
+
|
21
|
+
# not sure why, but we don't have time to care about Ruby 1.8 too much
|
22
|
+
case $RUBY_VERSION in
|
23
|
+
1.8.*) skip_models WriterThreadSpawn WriterThreadPool ;;
|
24
|
+
esac
|
25
|
+
|
26
|
+
t_plan 13 "Kgio autopush tests"
|
27
|
+
|
28
|
+
start_strace () {
|
29
|
+
# dbgcat strace_out
|
30
|
+
> $strace_out
|
31
|
+
sleep 1
|
32
|
+
strace -p $worker_pid -e '!futex' -f -o $strace_out &
|
33
|
+
strace_pid=$!
|
34
|
+
while ! test -s $strace_out; do sleep 1; done
|
35
|
+
}
|
36
|
+
|
37
|
+
check_TCP_CORK () {
|
38
|
+
nr=0
|
39
|
+
while test 2 -gt $(grep TCP_CORK $strace_out | wc -l)
|
40
|
+
do
|
41
|
+
nr=$(( $nr + 1 ))
|
42
|
+
if test $nr -gt 30
|
43
|
+
then
|
44
|
+
dbgcat strace_out
|
45
|
+
die "waited too long ($nr seconds) for TCP_CORK"
|
46
|
+
fi
|
47
|
+
sleep 1
|
48
|
+
done
|
49
|
+
|
50
|
+
test 2 -eq $(grep TCP_CORK $strace_out | wc -l)
|
51
|
+
fgrep 'SOL_TCP, TCP_CORK, [0], 4) = 0' $strace_out
|
52
|
+
fgrep 'SOL_TCP, TCP_CORK, [1], 4) = 0' $strace_out
|
53
|
+
}
|
54
|
+
|
55
|
+
t_begin "setup and start" && {
|
56
|
+
rainbows_setup $model 1 1
|
57
|
+
rtmpfiles strace_out
|
58
|
+
ed -s $unicorn_config <<EOF
|
59
|
+
,s/^listen.*/listen "$listen", :tcp_nodelay => true, :tcp_nopush => true/
|
60
|
+
w
|
61
|
+
EOF
|
62
|
+
rainbows -D large-file-response.ru -c $unicorn_config -E none
|
63
|
+
rainbows_wait_start
|
64
|
+
}
|
65
|
+
|
66
|
+
t_begin "read worker pid" && {
|
67
|
+
worker_pid=$(curl -sSf http://$listen/pid)
|
68
|
+
kill -0 $worker_pid
|
69
|
+
}
|
70
|
+
|
71
|
+
t_begin "start strace on worker" && start_strace
|
72
|
+
|
73
|
+
t_begin "reading RSS uncorks" && {
|
74
|
+
curl -sSf http://$listen/rss >/dev/null
|
75
|
+
}
|
76
|
+
|
77
|
+
t_begin "restart strace on worker" && {
|
78
|
+
kill $strace_pid
|
79
|
+
wait
|
80
|
+
start_strace
|
81
|
+
}
|
82
|
+
|
83
|
+
t_begin "reading static file uncorks" && {
|
84
|
+
curl -sSf http://$listen/random_blob >/dev/null
|
85
|
+
check_TCP_CORK
|
86
|
+
}
|
87
|
+
|
88
|
+
t_begin "stop strace on worker" && {
|
89
|
+
kill $strace_pid
|
90
|
+
wait
|
91
|
+
}
|
92
|
+
|
93
|
+
t_begin "enable sendfile" && {
|
94
|
+
echo >> $unicorn_config 'require "sendfile"'
|
95
|
+
kill -HUP $rainbows_pid
|
96
|
+
test xSTART = x"$(cat $fifo)"
|
97
|
+
}
|
98
|
+
|
99
|
+
t_begin "reread worker pid" && {
|
100
|
+
worker_pid=$(curl -sSf http://$listen/pid)
|
101
|
+
kill -0 $worker_pid
|
102
|
+
}
|
103
|
+
|
104
|
+
t_begin "restart strace on the worker" && start_strace
|
105
|
+
|
106
|
+
t_begin "HTTP/1.x GET on static file with sendfile uncorks" && {
|
107
|
+
curl -sSf http://$listen/random_blob >/dev/null
|
108
|
+
check_TCP_CORK
|
109
|
+
}
|
110
|
+
|
111
|
+
t_begin "killing succeeds" && {
|
112
|
+
kill $strace_pid
|
113
|
+
wait
|
114
|
+
# dbgcat strace_out
|
115
|
+
kill $rainbows_pid
|
116
|
+
}
|
117
|
+
|
118
|
+
t_begin "check stderr" && check_stderr
|
119
|
+
|
120
|
+
t_done
|
data/t/test_isolate.rb
CHANGED
@@ -38,10 +38,10 @@ Isolate.now!(opts) do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
if RUBY_PLATFORM =~ /linux/
|
41
|
-
gem 'sleepy_penguin', '
|
41
|
+
gem 'sleepy_penguin', '3.0.1'
|
42
42
|
|
43
43
|
# is 2.6.32 new enough?
|
44
|
-
gem 'io_splice', '4.1.
|
44
|
+
gem 'io_splice', '4.1.1' if `uname -r`.strip > '2.6.32'
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rainbows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 3
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 3.
|
10
|
+
version: 3.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Rainbows! hackers
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-21 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rack
|
@@ -458,6 +458,8 @@ files:
|
|
458
458
|
- t/t0040-keepalive_requests-setting.sh
|
459
459
|
- t/t0041-optional-pool-size.sh
|
460
460
|
- t/t0042-client_header_buffer_size.sh
|
461
|
+
- t/t0043-quit-keepalive-disconnect.sh
|
462
|
+
- t/t0044-autopush.sh
|
461
463
|
- t/t0050-response-body-close-has-env.sh
|
462
464
|
- t/t0100-rack-input-hammer-chunked.sh
|
463
465
|
- t/t0100-rack-input-hammer-content-length.sh
|