rainbows 0.90.2 → 0.91.0

Sign up to get free protection for your applications and to get access to all the features.
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.90.2.GIT
4
+ DEF_VER=v0.91.0.GIT
5
5
 
6
6
  LF='
7
7
  '
data/GNUmakefile CHANGED
@@ -58,7 +58,7 @@ NEWS: GIT-VERSION-FILE
58
58
  $(RAKE) -s news_rdoc > $@+
59
59
  mv $@+ $@
60
60
 
61
- SINCE = 0.9.0
61
+ SINCE = 0.90.0
62
62
  ChangeLog: LOG_VERSION = \
63
63
  $(shell git rev-parse -q "$(GIT_VERSION)" >/dev/null 2>&1 && \
64
64
  echo $(GIT_VERSION) || git describe)
data/bin/rainbows CHANGED
@@ -113,49 +113,11 @@ end
113
113
  config = ARGV[0] || "config.ru"
114
114
  abort "configuration file #{config} not found" unless File.exist?(config)
115
115
 
116
- if config =~ /\.ru$/
117
- # parse embedded command-line options in config.ru comments
118
- if File.open(config, "rb") { |fp| fp.sysread(fp.stat.size) } =~ /^#\\(.*)/
119
- opts.parse! $1.split(/\s+/)
120
- end
121
- end
122
-
123
- require 'pp' if $DEBUG
124
-
125
- app = lambda do ||
126
- # require Rack as late as possible in case $LOAD_PATH is modified
127
- # in config.ru or command-line
128
- inner_app = case config
129
- when /\.ru$/
130
- raw = File.open(config, "rb") { |fp| fp.sysread(fp.stat.size) }
131
- raw.sub!(/^__END__\n.*/, '')
132
- eval("Rack::Builder.new {(#{raw}\n)}.to_app", nil, config)
133
- else
134
- require config
135
- Object.const_get(File.basename(config, '.rb').capitalize)
136
- end
137
- pp({ :inner_app => inner_app }) if $DEBUG
138
- case ENV["RACK_ENV"]
139
- when "development"
140
- Rack::Builder.new do
141
- use Rack::CommonLogger, $stderr
142
- use Rack::ShowExceptions
143
- use Rack::Lint
144
- run inner_app
145
- end.to_app
146
- when "deployment"
147
- Rack::Builder.new do
148
- use Rack::CommonLogger, $stderr
149
- run inner_app
150
- end.to_app
151
- else
152
- inner_app
153
- end
154
- end
155
-
116
+ app = Unicorn.builder(config, opts)
156
117
  listeners << "#{host}:#{port}" if set_listener
157
118
 
158
119
  if $DEBUG
120
+ require 'pp'
159
121
  pp({
160
122
  :unicorn_options => options,
161
123
  :app => app,
@@ -163,5 +125,5 @@ if $DEBUG
163
125
  })
164
126
  end
165
127
 
166
- Unicorn::Launcher.daemonize! if daemonize
128
+ Unicorn::Launcher.daemonize!(options) if daemonize
167
129
  Rainbows.run(app, options)
data/lib/rainbows.rb CHANGED
@@ -22,7 +22,7 @@ module Rainbows
22
22
  false
23
23
  end
24
24
  end
25
- G = State.new(true, 0, 0, 2)
25
+ G = State.new(true, 0, 0, 5)
26
26
  O = {}
27
27
 
28
28
  require 'rainbows/const'
@@ -59,30 +59,19 @@ module Rainbows
59
59
  end
60
60
 
61
61
  # returns nil if accept fails
62
- if defined?(Fcntl::FD_CLOEXEC)
63
- def sync_accept(sock)
64
- rv = sock.accept
65
- rv.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
66
- rv
67
- rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EINTR
68
- end
69
-
70
- def accept(sock)
71
- rv = sock.accept_nonblock
72
- rv.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
73
- rv
74
- rescue Errno::EAGAIN, Errno::ECONNABORTED
75
- end
76
- else
77
- def sync_accept(sock)
78
- sock.accept
79
- rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EINTR
80
- end
62
+ def sync_accept(sock)
63
+ rv = sock.accept
64
+ rv.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
65
+ rv
66
+ rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EINTR
67
+ end
81
68
 
82
- def accept(sock)
83
- sock.accept_nonblock
84
- rescue Errno::EAGAIN, Errno::ECONNABORTED
85
- end
69
+ # returns nil if accept fails
70
+ def accept(sock)
71
+ rv = sock.accept_nonblock
72
+ rv.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
73
+ rv
74
+ rescue Errno::EAGAIN, Errno::ECONNABORTED
86
75
  end
87
76
  end
88
77
 
@@ -3,7 +3,7 @@
3
3
  module Rainbows
4
4
 
5
5
  module Const
6
- RAINBOWS_VERSION = '0.90.2'
6
+ RAINBOWS_VERSION = '0.91.0'
7
7
 
8
8
  include Unicorn::Const
9
9
 
@@ -28,7 +28,8 @@ module Rainbows
28
28
 
29
29
  def response(e)
30
30
  case e
31
- when EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
31
+ when EOFError, Errno::ECONNRESET, Errno::EPIPE, Errno::EINVAL,
32
+ Errno::EBADF, Errno::ENOTCONN
32
33
  # swallow error if client shuts down one end or disconnects
33
34
  when Unicorn::HttpParserError
34
35
  Const::ERROR_400_RESPONSE # try to tell the client they're bad
@@ -50,7 +50,7 @@ module Rainbows
50
50
  @env.delete(HTTP_EXPECT)
51
51
  end
52
52
  @input = len && len <= MAX_BODY ? StringIO.new("") : Util.tmpio
53
- @hp.filter_body(@buf2 = @buf.dup, @buf)
53
+ @hp.filter_body(@buf2 = "", @buf)
54
54
  @input << @buf2
55
55
  on_read("")
56
56
  end
@@ -5,13 +5,13 @@ module Rainbows
5
5
  module Fiber
6
6
 
7
7
  # blocked readers (key: Rainbows::Fiber::IO object, value is irrelevant)
8
- RD = {}
8
+ RD = {}.compare_by_identity
9
9
 
10
10
  # blocked writers (key: Rainbows::Fiber::IO object, value is irrelevant)
11
- WR = {}
11
+ WR = {}.compare_by_identity
12
12
 
13
13
  # sleeping fibers go here (key: Fiber object, value: wakeup time)
14
- ZZ = {}
14
+ ZZ = {}.compare_by_identity
15
15
 
16
16
  # puts the current Fiber into uninterruptible sleep for at least
17
17
  # +seconds+. Unlike Kernel#sleep, this it is not possible to sleep
@@ -103,10 +103,8 @@ module Rainbows
103
103
  Error.write(io, e)
104
104
  ensure
105
105
  G.cur -= 1
106
- RD.delete(client)
107
- WR.delete(client)
108
106
  ZZ.delete(client.f)
109
- io.close unless io.closed?
107
+ client.close
110
108
  end
111
109
 
112
110
  end
@@ -19,7 +19,9 @@ module Rainbows
19
19
  end
20
20
 
21
21
  def close
22
- to_io.close
22
+ RD.delete(self)
23
+ WR.delete(self)
24
+ to_io.close unless to_io.closed?
23
25
  end
24
26
 
25
27
  def wait_readable
data/lib/rainbows/rev.rb CHANGED
@@ -31,6 +31,11 @@ module Rainbows
31
31
  # all connected clients
32
32
  CONN = {}
33
33
 
34
+ if {}.respond_to?(:compare_by_identity)
35
+ CONN.compare_by_identity
36
+ KATO.compare_by_identity
37
+ end
38
+
34
39
  include Core
35
40
  end
36
41
  end
@@ -30,8 +30,8 @@ module Rainbows
30
30
  # once a client is accepted, it is processed in its entirety here
31
31
  # in 3 easy steps: read request, call app, write app response
32
32
  def process_client(client)
33
- defined?(Fcntl::FD_CLOEXEC) and
34
- client.instance_eval { @_io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) }
33
+ io = client.instance_variable_get(:@_io)
34
+ io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
35
35
  rd_args = [ nil ]
36
36
  remote_addr = if ::Revactor::TCP::Socket === client
37
37
  rd_args << RD_ARGS
@@ -68,7 +68,7 @@ module Rainbows
68
68
  end while alive and hp.reset.nil? and env.clear
69
69
  rescue ::Revactor::TCP::ReadError
70
70
  rescue => e
71
- Error.write(client.instance_eval { @_io }, e)
71
+ Error.write(io, e)
72
72
  ensure
73
73
  client.close
74
74
  end
@@ -86,7 +86,7 @@ module Rainbows
86
86
  revactorize_listeners.each do |l, close, accept|
87
87
  Actor.spawn(l, close, accept) do |l, close, accept|
88
88
  Actor.current.trap_exit = true
89
- l.controller = l.instance_eval { @receiver = Actor.current }
89
+ l.controller = l.instance_variable_set(:@receiver, Actor.current)
90
90
  begin
91
91
  while nr >= limit
92
92
  l.disable if l.enabled?
@@ -118,7 +118,8 @@ module Rainbows
118
118
  end
119
119
 
120
120
  Actor.sleep 1 while G.tick || nr > 0
121
- rescue Errno::EMFILE => e
121
+ rescue Errno::EMFILE
122
+ # ignore, let another worker process take it
122
123
  end
123
124
 
124
125
  def revactorize_listeners
@@ -22,11 +22,11 @@ module Rainbows
22
22
  def tee(length, dst)
23
23
  unless parser.body_eof?
24
24
  if parser.filter_body(dst, buf << socket.read).nil?
25
- @tmp.write(dst)
25
+ tmp.write(dst)
26
26
  diff = dst.size - length
27
27
  if diff > 0
28
28
  dst.replace(dst[0,length])
29
- @tmp.seek(-diff, IO::SEEK_CUR)
29
+ tmp.seek(-diff, IO::SEEK_CUR)
30
30
  end
31
31
  return dst
32
32
  end
data/rainbows.gemspec CHANGED
@@ -43,7 +43,7 @@ Gem::Specification.new do |s|
43
43
  # we need Unicorn for the HTTP parser and process management
44
44
  # The HTTP parser in Unicorn < 0.96.1 did not use the Ruby
45
45
  # API correctly and resulted in a memory leak
46
- s.add_dependency(%q<unicorn>, ["~> 0.96.1", "< 0.97.0"])
46
+ s.add_dependency(%q<unicorn>, ["~> 0.97.0"])
47
47
 
48
48
  # Unicorn already depends on Rack
49
49
  # s.add_dependency(%q<rack>)
@@ -0,0 +1,54 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 7 "reload config.ru error with preload_app true"
4
+
5
+ t_begin "setup and start" && {
6
+ rainbows_setup
7
+ rtmpfiles ru
8
+
9
+ cat > $ru <<\EOF
10
+ use Rack::ContentLength
11
+ use Rack::ContentType, "text/plain"
12
+ x = { "hello" => "world" }
13
+ run lambda { |env| [ 200, {}, [ x.inspect << "\n" ] ] }
14
+ EOF
15
+ echo 'preload_app true' >> $unicorn_config
16
+ rainbows -D -c $unicorn_config $ru
17
+ rainbows_wait_start
18
+ }
19
+
20
+ t_begin "hit with curl" && {
21
+ out=$(curl -sSf http://$listen/)
22
+ test x"$out" = x'{"hello"=>"world"}'
23
+ }
24
+
25
+ t_begin "introduce syntax error in rackup file" && {
26
+ echo '...' >> $ru
27
+ }
28
+
29
+ t_begin "reload signal succeeds" && {
30
+ kill -HUP $rainbows_pid
31
+ rainbows_wait_start
32
+ while ! egrep '(done|error) reloading' $r_err >/dev/null
33
+ do
34
+ sleep 1
35
+ done
36
+
37
+ grep 'error reloading' $r_err >/dev/null
38
+ > $r_err
39
+ }
40
+
41
+ t_begin "hit with curl" && {
42
+ out=$(curl -sSf http://$listen/)
43
+ test x"$out" = x'{"hello"=>"world"}'
44
+ }
45
+
46
+ t_begin "killing succeeds" && {
47
+ kill $rainbows_pid
48
+ }
49
+
50
+ t_begin "check stderr" && {
51
+ check_stderr
52
+ }
53
+
54
+ t_done
@@ -0,0 +1,50 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 6 "config variables conflict with preload_app"
4
+
5
+ t_begin "setup and start" && {
6
+ rainbows_setup
7
+ rtmpfiles ru rutmp
8
+
9
+ cat > $ru <<\EOF
10
+ use Rack::ContentLength
11
+ use Rack::ContentType, "text/plain"
12
+ config = ru = { "hello" => "world" }
13
+ run lambda { |env| [ 200, {}, [ ru.inspect << "\n" ] ] }
14
+ EOF
15
+ echo 'preload_app true' >> $unicorn_config
16
+ rainbows -D -c $unicorn_config $ru
17
+ rainbows_wait_start
18
+ }
19
+
20
+ t_begin "hit with curl" && {
21
+ out=$(curl -sSf http://$listen/)
22
+ test x"$out" = x'{"hello"=>"world"}'
23
+ }
24
+
25
+ t_begin "modify rackup file" && {
26
+ sed -e 's/world/WORLD/' < $ru > $rutmp
27
+ mv $rutmp $ru
28
+ }
29
+
30
+ t_begin "reload signal succeeds" && {
31
+ kill -HUP $rainbows_pid
32
+ rainbows_wait_start
33
+ while ! egrep '(done|error) reloading' < $r_err >/dev/null
34
+ do
35
+ sleep 1
36
+ done
37
+
38
+ grep 'done reloading' $r_err >/dev/null
39
+ }
40
+
41
+ t_begin "hit with curl" && {
42
+ out=$(curl -sSf http://$listen/)
43
+ test x"$out" = x'{"hello"=>"WORLD"}'
44
+ }
45
+
46
+ t_begin "killing succeeds" && {
47
+ kill $rainbows_pid
48
+ }
49
+
50
+ t_done
data/t/test-lib.sh CHANGED
@@ -99,13 +99,7 @@ pid "$pid"
99
99
  stderr_path "$r_err"
100
100
  stdout_path "$r_out"
101
101
 
102
- # close my-tap-lib.sh FDs
103
- unless ENV['UNICORN_FD']
104
- IO.for_fd(3).close rescue nil
105
- IO.for_fd(4).close rescue nil
106
- end
107
-
108
- before_fork do |server, worker|
102
+ after_fork do |server, worker|
109
103
  # test script will block while reading from $fifo,
110
104
  # so notify the script on the first worker we spawn
111
105
  # by opening the FIFO
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rainbows
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.90.2
4
+ version: 0.91.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rainbows! hackers
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-13 00:00:00 +00:00
12
+ date: 2010-03-01 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -19,9 +19,6 @@ dependencies:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
21
  - - ~>
22
- - !ruby/object:Gem::Version
23
- version: 0.96.1
24
- - - <
25
22
  - !ruby/object:Gem::Version
26
23
  version: 0.97.0
27
24
  version:
@@ -202,6 +199,8 @@ files:
202
199
  - t/t0010-keepalive-timeout-effective.sh
203
200
  - t/t0011-close-on-exec-set.sh
204
201
  - t/t0012-spurious-wakeups-quiet.sh
202
+ - t/t0013-reload-bad-config.sh
203
+ - t/t0014-config-conflict.sh
205
204
  - t/t0100-rack-input-hammer.sh
206
205
  - t/t0101-rack-input-trailer.sh
207
206
  - t/t0102-rack-input-short.sh