rainbows 0.1.1 → 0.2.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/.document +6 -5
- data/DEPLOY +13 -0
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +1 -1
- data/README +32 -6
- data/SIGNALS +11 -7
- data/TODO +2 -3
- data/lib/rainbows.rb +10 -3
- data/lib/rainbows/app_pool.rb +90 -0
- data/lib/rainbows/base.rb +41 -4
- data/lib/rainbows/const.rb +1 -6
- data/lib/rainbows/http_server.rb +1 -1
- data/lib/rainbows/rev.rb +174 -0
- data/lib/rainbows/revactor.rb +40 -37
- data/lib/rainbows/thread_pool.rb +31 -57
- data/lib/rainbows/thread_spawn.rb +32 -45
- data/local.mk.sample +4 -3
- data/t/.gitignore +1 -2
- data/t/GNUmakefile +21 -7
- data/t/README +42 -0
- data/t/bin/content-md5-put +36 -0
- data/t/bin/unused_listen +1 -1
- data/t/content-md5.ru +23 -0
- data/t/sleep.ru +11 -0
- data/t/t0000-basic.sh +29 -3
- data/t/t1000-thread-pool-basic.sh +5 -6
- data/t/t1000.ru +5 -1
- data/t/t1002-thread-pool-graceful.sh +37 -0
- data/t/t2000-thread-spawn-basic.sh +4 -6
- data/t/t2000.ru +5 -1
- data/t/t2002-thread-spawn-graceful.sh +37 -0
- data/t/t3000-revactor-basic.sh +4 -6
- data/t/t3000.ru +5 -1
- data/t/t3001-revactor-pipeline.sh +46 -0
- data/t/t3002-revactor-graceful.sh +38 -0
- data/t/t3003-revactor-reopen-logs.sh +54 -0
- data/t/t3100-revactor-tee-input.sh +8 -13
- data/t/t4000-rev-basic.sh +51 -0
- data/t/t4000.ru +9 -0
- data/t/t4002-rev-graceful.sh +52 -0
- data/t/t4003-rev-parser-error.sh +34 -0
- data/t/t4100-rev-rack-input.sh +44 -0
- data/t/t4101-rev-rack-input-trailer.sh +51 -0
- data/t/t9000-rack-app-pool.sh +37 -0
- data/t/t9000.ru +14 -0
- data/t/test-lib.sh +29 -2
- data/vs_Unicorn +50 -1
- metadata +28 -6
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
require_revactor
|
4
|
+
|
5
|
+
eval $(unused_listen)
|
6
|
+
rtmpfiles unicorn_config curl_out curl_err pid r_err r_out r_rot
|
7
|
+
|
8
|
+
nr_client=30
|
9
|
+
nr_actor=10
|
10
|
+
|
11
|
+
cat > $unicorn_config <<EOF
|
12
|
+
listen "$listen"
|
13
|
+
pid "$pid"
|
14
|
+
stderr_path "$r_err"
|
15
|
+
stdout_path "$r_out"
|
16
|
+
Rainbows! do
|
17
|
+
use :Revactor
|
18
|
+
worker_connections $nr_actor
|
19
|
+
end
|
20
|
+
EOF
|
21
|
+
|
22
|
+
SLEEP_CLASS=Actor rainbows -D sleep.ru -c $unicorn_config
|
23
|
+
wait_for_pid $pid
|
24
|
+
|
25
|
+
start=$(date +%s)
|
26
|
+
for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
|
27
|
+
do
|
28
|
+
( curl -sSf http://$listen/2 >> $curl_out 2>> $curl_err ) &
|
29
|
+
done
|
30
|
+
! grep Error $r_err
|
31
|
+
|
32
|
+
rm $r_rot
|
33
|
+
mv $r_err $r_rot
|
34
|
+
|
35
|
+
kill -USR1 $(cat $pid)
|
36
|
+
wait_for_pid $r_err
|
37
|
+
|
38
|
+
dbgcat r_rot
|
39
|
+
dbgcat r_err
|
40
|
+
|
41
|
+
wait
|
42
|
+
echo elapsed=$(( $(date +%s) - $start ))
|
43
|
+
! test -s $curl_err
|
44
|
+
test x"$(wc -l < $curl_out)" = x$nr_client
|
45
|
+
nr=$(sort < $curl_out | uniq | wc -l)
|
46
|
+
|
47
|
+
test "$nr" -eq 1
|
48
|
+
test x$(sort < $curl_out | uniq) = xHello
|
49
|
+
! grep Error $r_err
|
50
|
+
! grep Error $r_rot
|
51
|
+
|
52
|
+
kill $(cat $pid)
|
53
|
+
dbgcat r_err
|
54
|
+
! grep Error $r_err
|
@@ -4,17 +4,10 @@ nr_actor=${nr_actor-50}
|
|
4
4
|
|
5
5
|
. ./test-lib.sh
|
6
6
|
require_revactor
|
7
|
+
test -r random_blob || die "random_blob required, run with 'make $0'"
|
7
8
|
|
8
9
|
eval $(unused_listen)
|
9
|
-
unicorn_config
|
10
|
-
curl_out=$(mktemp -t rainbows.$$.curl.out.XXXXXXXX)
|
11
|
-
curl_err=$(mktemp -t rainbows.$$.curl.err.XXXXXXXX)
|
12
|
-
r_err=$(mktemp -t rainbows.$$.r.err.XXXXXXXX)
|
13
|
-
r_out=$(mktemp -t rainbows.$$.r.out.XXXXXXXX)
|
14
|
-
pid=$(mktemp -t rainbows.$$.pid.XXXXXXXX)
|
15
|
-
blob=$(mktemp -t rainbows.$$.blob.XXXXXXXX)
|
16
|
-
TEST_RM_LIST="$TEST_RM_LIST $unicorn_config $lock_path $r_err $r_out"
|
17
|
-
TEST_RM_LIST="$TEST_RM_LIST $curl_out $curl_err $blob $pid"
|
10
|
+
rtmpfiles unicorn_config curl_out curl_err r_err r_out pid
|
18
11
|
|
19
12
|
cat > $unicorn_config <<EOF
|
20
13
|
listen "$listen"
|
@@ -31,12 +24,13 @@ echo pid=$pid
|
|
31
24
|
rainbows -D sha1.ru -c $unicorn_config
|
32
25
|
wait_for_pid $pid
|
33
26
|
|
34
|
-
dd if=/dev/urandom bs=1M count=10 of=$blob 2>/dev/null
|
35
|
-
|
36
27
|
start=$(date +%s)
|
37
28
|
for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
|
38
29
|
do
|
39
|
-
(
|
30
|
+
(
|
31
|
+
curl -sSf -T- http://$listen/$i \
|
32
|
+
< random_blob >> $curl_out 2>> $curl_err
|
33
|
+
) &
|
40
34
|
done
|
41
35
|
wait
|
42
36
|
echo elapsed=$(( $(date +%s) - $start ))
|
@@ -44,6 +38,7 @@ echo elapsed=$(( $(date +%s) - $start ))
|
|
44
38
|
kill $(cat $pid)
|
45
39
|
test $nr_client -eq $(wc -l < $curl_out)
|
46
40
|
test 1 -eq $(sort < $curl_out | uniq | wc -l)
|
47
|
-
blob_sha1=$( expr "$(sha1sum <
|
41
|
+
blob_sha1=$( expr "$(sha1sum < random_blob)" : '\([a-f0-9]\+\)')
|
48
42
|
echo blob_sha1=$blob_sha1
|
49
43
|
test x"$blob_sha1" = x"$(sort < $curl_out | uniq)"
|
44
|
+
! grep Error $r_err
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
require_rev
|
4
|
+
|
5
|
+
eval $(unused_listen)
|
6
|
+
rtmpfiles unicorn_config pid r_err r_out tmp fifo ok
|
7
|
+
rm -f $fifo
|
8
|
+
mkfifo $fifo
|
9
|
+
|
10
|
+
nr_client=30
|
11
|
+
|
12
|
+
cat > $unicorn_config <<EOF
|
13
|
+
listen "$listen"
|
14
|
+
pid "$pid"
|
15
|
+
stderr_path "$r_err"
|
16
|
+
stdout_path "$r_out"
|
17
|
+
Rainbows! do
|
18
|
+
use :Rev
|
19
|
+
worker_connections 50
|
20
|
+
end
|
21
|
+
EOF
|
22
|
+
|
23
|
+
rainbows -D t4000.ru -c $unicorn_config
|
24
|
+
wait_for_pid $pid
|
25
|
+
|
26
|
+
echo "single request"
|
27
|
+
curl -sSfv http://$listen/
|
28
|
+
|
29
|
+
echo "two requests with keepalive"
|
30
|
+
curl -sSfv http://$listen/a http://$listen/b > $tmp 2>&1
|
31
|
+
grep 'Re-using existing connection' < $tmp
|
32
|
+
|
33
|
+
echo "pipelining partial requests"
|
34
|
+
req='GET / HTTP/1.1\r\nHost: example.com\r\n'
|
35
|
+
(
|
36
|
+
printf "$req"'\r\n'"$req"
|
37
|
+
cat $fifo > $tmp &
|
38
|
+
sleep 1
|
39
|
+
printf 'Connection: close\r\n\r\n'
|
40
|
+
wait
|
41
|
+
echo ok > $ok
|
42
|
+
) | socat - TCP:$listen > $fifo
|
43
|
+
|
44
|
+
kill $(cat $pid)
|
45
|
+
|
46
|
+
test 2 -eq $(grep '^HTTP/1.1' $tmp | wc -l)
|
47
|
+
test 2 -eq $(grep '^HTTP/1.1 200 OK' $tmp | wc -l)
|
48
|
+
test 1 -eq $(grep '^Connection: keep-alive' $tmp | wc -l)
|
49
|
+
test 1 -eq $(grep '^Connection: close' $tmp | wc -l)
|
50
|
+
test x"$(cat $ok)" = xok
|
51
|
+
! grep Error $r_err
|
data/t/t4000.ru
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
require_rev
|
4
|
+
|
5
|
+
eval $(unused_listen)
|
6
|
+
rtmpfiles unicorn_config tmp pid r_err r_out out
|
7
|
+
nr_client=10
|
8
|
+
cat > $unicorn_config <<EOF
|
9
|
+
listen "$listen"
|
10
|
+
stderr_path "$r_err"
|
11
|
+
stdout_path "$r_out"
|
12
|
+
pid "$pid"
|
13
|
+
Rainbows! do
|
14
|
+
use :Rev
|
15
|
+
end
|
16
|
+
EOF
|
17
|
+
|
18
|
+
rainbows -D sleep.ru -c $unicorn_config
|
19
|
+
wait_for_pid $pid
|
20
|
+
|
21
|
+
for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
|
22
|
+
do
|
23
|
+
(
|
24
|
+
rtmpfiles fifo tmp
|
25
|
+
rm -f $fifo
|
26
|
+
mkfifo $fifo
|
27
|
+
(
|
28
|
+
printf 'GET /0 HTTP/1.1\r\n'
|
29
|
+
cat $fifo > $tmp &
|
30
|
+
sleep 1
|
31
|
+
printf 'Host: example.com\r\n'
|
32
|
+
sleep 1
|
33
|
+
printf 'Connection: close\r\n'
|
34
|
+
sleep 1
|
35
|
+
printf '\r\n'
|
36
|
+
wait
|
37
|
+
) | socat - TCP:$listen > $fifo
|
38
|
+
fgrep 'Hello' $tmp >> $out || :
|
39
|
+
rm -f $fifo $tmp
|
40
|
+
) &
|
41
|
+
done
|
42
|
+
|
43
|
+
sleep 2 # potentially racy :<
|
44
|
+
kill -QUIT $(cat $pid)
|
45
|
+
wait
|
46
|
+
|
47
|
+
test x"$(wc -l < $out)" = x$nr_client
|
48
|
+
nr=$(sort < $out | uniq | wc -l)
|
49
|
+
test "$nr" -eq 1
|
50
|
+
|
51
|
+
test x$(sort < $out | uniq) = xHello
|
52
|
+
! grep Error $r_err
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
require_rev
|
4
|
+
|
5
|
+
eval $(unused_listen)
|
6
|
+
rtmpfiles unicorn_config pid r_err r_out tmp fifo ok
|
7
|
+
rm -f $fifo
|
8
|
+
mkfifo $fifo
|
9
|
+
|
10
|
+
cat > $unicorn_config <<EOF
|
11
|
+
listen "$listen"
|
12
|
+
pid "$pid"
|
13
|
+
stderr_path "$r_err"
|
14
|
+
stdout_path "$r_out"
|
15
|
+
Rainbows! do
|
16
|
+
use :Rev
|
17
|
+
end
|
18
|
+
EOF
|
19
|
+
|
20
|
+
rainbows -D t4000.ru -c $unicorn_config
|
21
|
+
wait_for_pid $pid
|
22
|
+
|
23
|
+
(
|
24
|
+
printf 'GET / HTTP/1/1\r\nHost: example.com\r\n\r\n'
|
25
|
+
cat $fifo > $tmp &
|
26
|
+
wait
|
27
|
+
echo ok > $ok
|
28
|
+
) | socat - TCP:$listen > $fifo
|
29
|
+
|
30
|
+
kill $(cat $pid)
|
31
|
+
|
32
|
+
dbgcat tmp
|
33
|
+
grep -F 'HTTP/1.1 400 Bad Request' $tmp
|
34
|
+
! grep Error $r_err
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
nr_client=${nr_client-25}
|
3
|
+
nr=${nr-50}
|
4
|
+
|
5
|
+
. ./test-lib.sh
|
6
|
+
require_rev
|
7
|
+
test -r random_blob || die "random_blob required, run with 'make $0'"
|
8
|
+
|
9
|
+
eval $(unused_listen)
|
10
|
+
rtmpfiles unicorn_config curl_out curl_err r_err r_out pid
|
11
|
+
|
12
|
+
cat > $unicorn_config <<EOF
|
13
|
+
listen "$listen"
|
14
|
+
pid "$pid"
|
15
|
+
stderr_path "$r_err"
|
16
|
+
stdout_path "$r_out"
|
17
|
+
Rainbows! do
|
18
|
+
use :Rev
|
19
|
+
worker_connections $nr
|
20
|
+
end
|
21
|
+
EOF
|
22
|
+
|
23
|
+
echo pid=$pid
|
24
|
+
rainbows -D sha1.ru -c $unicorn_config
|
25
|
+
wait_for_pid $pid
|
26
|
+
|
27
|
+
start=$(date +%s)
|
28
|
+
for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
|
29
|
+
do
|
30
|
+
(
|
31
|
+
curl -sSf -T- http://$listen/$i \
|
32
|
+
< random_blob >> $curl_out 2>> $curl_err
|
33
|
+
) &
|
34
|
+
done
|
35
|
+
wait
|
36
|
+
echo elapsed=$(( $(date +%s) - $start ))
|
37
|
+
|
38
|
+
kill $(cat $pid)
|
39
|
+
test $nr_client -eq $(wc -l < $curl_out)
|
40
|
+
test 1 -eq $(sort < $curl_out | uniq | wc -l)
|
41
|
+
blob_sha1=$( expr "$(sha1sum < random_blob)" : '\([a-f0-9]\+\)')
|
42
|
+
echo blob_sha1=$blob_sha1
|
43
|
+
test x"$blob_sha1" = x"$(sort < $curl_out | uniq)"
|
44
|
+
! grep Error $r_err
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
nr_client=${nr_client-25}
|
3
|
+
nr=${nr-50}
|
4
|
+
|
5
|
+
. ./test-lib.sh
|
6
|
+
require_rev
|
7
|
+
test -r random_blob || die "random_blob required, run with 'make $0'"
|
8
|
+
|
9
|
+
eval $(unused_listen)
|
10
|
+
rtmpfiles unicorn_config tmp r_err r_out pid fifo ok
|
11
|
+
rm -f $fifo
|
12
|
+
mkfifo $fifo
|
13
|
+
|
14
|
+
cat > $unicorn_config <<EOF
|
15
|
+
listen "$listen"
|
16
|
+
pid "$pid"
|
17
|
+
stderr_path "$r_err"
|
18
|
+
stdout_path "$r_out"
|
19
|
+
Rainbows! do
|
20
|
+
use :Rev
|
21
|
+
end
|
22
|
+
EOF
|
23
|
+
|
24
|
+
rainbows -D content-md5.ru -c $unicorn_config
|
25
|
+
wait_for_pid $pid
|
26
|
+
|
27
|
+
echo "small blob"
|
28
|
+
(
|
29
|
+
echo hello world | content-md5-put
|
30
|
+
cat $fifo > $tmp &
|
31
|
+
wait
|
32
|
+
echo ok > $ok
|
33
|
+
) | socat - TCP:$listen | tee $fifo
|
34
|
+
|
35
|
+
fgrep 'HTTP/1.1 200 OK' $tmp
|
36
|
+
test xok = x"$(cat $ok)"
|
37
|
+
! grep Error $r_err
|
38
|
+
|
39
|
+
|
40
|
+
echo "big blob"
|
41
|
+
(
|
42
|
+
content-md5-put < random_blob
|
43
|
+
cat $fifo > $tmp &
|
44
|
+
wait
|
45
|
+
echo ok > $ok
|
46
|
+
) | socat - TCP:$listen | tee $fifo
|
47
|
+
|
48
|
+
fgrep 'HTTP/1.1 200 OK' $tmp
|
49
|
+
test xok = x"$(cat $ok)"
|
50
|
+
! grep Error $r_err
|
51
|
+
kill $(cat $pid)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
|
4
|
+
eval $(unused_listen)
|
5
|
+
rtmpfiles unicorn_config pid r_err r_out curl_out curl_err
|
6
|
+
|
7
|
+
nr_client=30
|
8
|
+
|
9
|
+
cat > $unicorn_config <<EOF
|
10
|
+
listen "$listen"
|
11
|
+
pid "$pid"
|
12
|
+
stderr_path "$r_err"
|
13
|
+
stdout_path "$r_out"
|
14
|
+
Rainbows! do
|
15
|
+
use :ThreadSpawn
|
16
|
+
worker_connections 50
|
17
|
+
end
|
18
|
+
EOF
|
19
|
+
|
20
|
+
APP_POOL_SIZE=4
|
21
|
+
APP_POOL_SIZE=$APP_POOL_SIZE rainbows -D t9000.ru -c $unicorn_config
|
22
|
+
wait_for_pid $pid
|
23
|
+
|
24
|
+
start=$(date +%s)
|
25
|
+
for i in $(awk "BEGIN{for(i=0;i<$nr_client;++i) print i}" </dev/null)
|
26
|
+
do
|
27
|
+
( curl -sSf http://$listen/ >> $curl_out 2>> $curl_err ) &
|
28
|
+
done
|
29
|
+
wait
|
30
|
+
echo elapsed=$(( $(date +%s) - $start ))
|
31
|
+
kill $(cat $pid)
|
32
|
+
|
33
|
+
test $APP_POOL_SIZE -eq $(sort < $curl_out | uniq | wc -l)
|
34
|
+
! test -s $curl_err
|
35
|
+
|
36
|
+
! grep Error $r_err
|
37
|
+
#
|
data/t/t9000.ru
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
use Rack::ContentLength
|
2
|
+
use Rack::ContentType
|
3
|
+
use Rainbows::AppPool, :size => ENV['APP_POOL_SIZE'].to_i
|
4
|
+
sleep_class = ENV['SLEEP_CLASS']
|
5
|
+
sleep_class = sleep_class ? Object.const_get(sleep_class) : Kernel
|
6
|
+
class Sleeper
|
7
|
+
def call(env)
|
8
|
+
sleep_class = ENV['SLEEP_CLASS']
|
9
|
+
sleep_class = sleep_class ? Object.const_get(sleep_class) : Kernel
|
10
|
+
sleep_class.sleep 1
|
11
|
+
[ 200, {}, [ "#{object_id}\n" ] ]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
run Sleeper.new
|
data/t/test-lib.sh
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
# Copyright (c) 2009 Rainbows! developers
|
3
|
+
|
4
|
+
set -o pipefail >/dev/null 2>&1 || : # non-POSIX, but useful in ksh/bash
|
3
5
|
set -e
|
4
6
|
set -u
|
5
7
|
T=$(basename $0)
|
@@ -15,8 +17,8 @@ die () {
|
|
15
17
|
exit 1
|
16
18
|
}
|
17
19
|
|
18
|
-
|
19
|
-
trap 'rm -f $
|
20
|
+
_TEST_RM_LIST=""
|
21
|
+
trap 'rm -f $_TEST_RM_LIST' 0
|
20
22
|
PATH=$PWD/bin:$PATH
|
21
23
|
export PATH
|
22
24
|
|
@@ -39,3 +41,28 @@ require_revactor () {
|
|
39
41
|
exit 0
|
40
42
|
fi
|
41
43
|
}
|
44
|
+
|
45
|
+
require_rev() {
|
46
|
+
if ! $ruby -rrev -e "puts Rev::VERSION" >/dev/null 2>&1
|
47
|
+
then
|
48
|
+
echo >&2 "skipping $T since we don't have Rev"
|
49
|
+
exit 0
|
50
|
+
fi
|
51
|
+
}
|
52
|
+
|
53
|
+
# given a list of variable names, create temporary files and assign
|
54
|
+
# the pathnames to those variables
|
55
|
+
rtmpfiles () {
|
56
|
+
for id in "$@"
|
57
|
+
do
|
58
|
+
_tmp=$(mktemp -t rainbows.$$.$id.XXXXXXXX)
|
59
|
+
eval "$id=$_tmp"
|
60
|
+
_TEST_RM_LIST="$_TEST_RM_LIST $_tmp"
|
61
|
+
done
|
62
|
+
}
|
63
|
+
|
64
|
+
dbgcat () {
|
65
|
+
id=$1
|
66
|
+
eval '_file=$'$id
|
67
|
+
sed -e "s/^/$id:/" < $_file
|
68
|
+
}
|