rainbows 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|