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