rainbows 0.90.2 → 0.91.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/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