rainbows 3.1.0 → 3.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/GIT-VERSION-GEN +1 -1
- data/README +2 -2
- data/Static_Files +4 -4
- data/TODO +1 -1
- data/lib/rainbows/client.rb +2 -1
- data/lib/rainbows/const.rb +1 -1
- data/lib/rainbows/coolio/client.rb +13 -12
- data/lib/rainbows/epoll/client.rb +6 -5
- data/lib/rainbows/fiber/body.rb +10 -9
- data/lib/rainbows/response.rb +5 -5
- data/lib/rainbows/revactor/client/methods.rb +9 -8
- data/lib/rainbows/stream_file.rb +1 -1
- data/lib/rainbows/writer_thread_pool/client.rb +1 -1
- data/lib/rainbows/writer_thread_spawn/client.rb +1 -1
- data/rainbows.gemspec +1 -1
- data/t/cramp/rainsocket.ru +3 -3
- data/t/cramp/streaming.ru +2 -2
- data/t/test_isolate.rb +6 -5
- data/t/test_isolate_cramp.rb +1 -1
- metadata +32 -4
data/GIT-VERSION-GEN
CHANGED
data/README
CHANGED
@@ -86,10 +86,10 @@ fast applications.
|
|
86
86
|
== License
|
87
87
|
|
88
88
|
\Rainbows! is copyright 2009,2010 by all contributors (see logs in git).
|
89
|
-
It is based on Mongrel and Unicorn and carries the same license.
|
89
|
+
It is based on Mongrel 1.1.5 and Unicorn and carries the same license.
|
90
90
|
|
91
91
|
Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed
|
92
|
-
under the Ruby license and the GPL2. See the included LICENSE file for
|
92
|
+
under the Ruby (1.8) license and the GPL2. See the included LICENSE file for
|
93
93
|
details.
|
94
94
|
|
95
95
|
\Rainbows! is 100% Free Software.
|
data/Static_Files
CHANGED
@@ -9,7 +9,7 @@ to simplify your deployments and only deploy one server?
|
|
9
9
|
|
10
10
|
== {sendfile}[http://rubygems.org/gems/sendfile] RubyGem
|
11
11
|
|
12
|
-
To enable the "sendfile" gem, just make sure you have 1.
|
12
|
+
To enable the "sendfile" gem, just make sure you have 1.1.0 or later and
|
13
13
|
"require" it in your \Rainbows!/Unicorn config file (not your Rack
|
14
14
|
config.ru):
|
15
15
|
|
@@ -26,7 +26,7 @@ config.ru):
|
|
26
26
|
The sendfile gem is works for all of our concurrency models except
|
27
27
|
NeverBlock and EventMachine (see below).
|
28
28
|
|
29
|
-
The sendfile gem is less buggy than current (Ruby 1.9.2
|
29
|
+
The sendfile gem is less buggy than current (Ruby 1.9.2)
|
30
30
|
IO.copy_stream and supports FreeBSD and Solaris in addition to Linux.
|
31
31
|
This RubyGem also works under Ruby 1.8 (even with threads) and should
|
32
32
|
work with rubinius.git, too.
|
@@ -40,9 +40,9 @@ their Writer* variants use the core IO.copy_stream method under Ruby
|
|
40
40
|
1.9. IO.copy_stream uses sendfile() under Linux, and a pread()/write()
|
41
41
|
loop (implemented in C) on other systems.
|
42
42
|
|
43
|
-
IO.copy_stream under Linux with Ruby 1.9.
|
43
|
+
IO.copy_stream under Linux with Ruby 1.9.2 (and before) is also
|
44
44
|
subject to hanging indefinitely when a client disconnected prematurely.
|
45
|
-
This issue is fixed in Ruby trunk (July 2010).
|
45
|
+
This issue is fixed in Ruby trunk (r28557, July 2010).
|
46
46
|
|
47
47
|
\Rainbows! supports IO.copy_stream since v0.93.0
|
48
48
|
|
data/TODO
CHANGED
@@ -11,7 +11,7 @@ care about.
|
|
11
11
|
* allow _OPTIONAL_ splice(2) with DevFdResponse under Linux
|
12
12
|
(splice is very broken under some older kernels)
|
13
13
|
|
14
|
-
* use IO#
|
14
|
+
* use IO#trysendfile for EventMachine/NeverBlock
|
15
15
|
|
16
16
|
* Open file cache Rack app/middleware (idea from nginx), since sendfile
|
17
17
|
(and IO.copy_stream) allows pread(2)-style offsets
|
data/lib/rainbows/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
# :enddoc:
|
3
|
+
require "io/wait"
|
3
4
|
|
4
5
|
# this class is used for most synchronous concurrency models
|
5
6
|
class Rainbows::Client < Kgio::Socket
|
@@ -8,7 +9,7 @@ class Rainbows::Client < Kgio::Socket
|
|
8
9
|
end
|
9
10
|
|
10
11
|
def kgio_wait_readable
|
11
|
-
|
12
|
+
wait Rainbows.keepalive_timeout
|
12
13
|
end
|
13
14
|
|
14
15
|
# used for reading headers (respecting keepalive_timeout)
|
data/lib/rainbows/const.rb
CHANGED
@@ -125,11 +125,8 @@ class Rainbows::Coolio::Client < Coolio::IO
|
|
125
125
|
when true then return # #next! will clear this bit
|
126
126
|
when nil # fall through
|
127
127
|
else
|
128
|
-
|
129
|
-
|
130
|
-
rescue EOFError # expected at file EOF
|
131
|
-
close_deferred # fall through
|
132
|
-
end
|
128
|
+
return if stream_file_chunk(@deferred)
|
129
|
+
close_deferred # EOF, fall through
|
133
130
|
end
|
134
131
|
|
135
132
|
case @state
|
@@ -179,7 +176,7 @@ class Rainbows::Coolio::Client < Coolio::IO
|
|
179
176
|
KATO.delete(self)
|
180
177
|
end
|
181
178
|
|
182
|
-
if IO.method_defined?(:
|
179
|
+
if IO.method_defined?(:trysendfile)
|
183
180
|
def defer_file(status, headers, body, alive, io, st)
|
184
181
|
if r = sendfile_range(status, headers)
|
185
182
|
status, headers, range = r
|
@@ -192,11 +189,15 @@ class Rainbows::Coolio::Client < Coolio::IO
|
|
192
189
|
end
|
193
190
|
|
194
191
|
def stream_file_chunk(sf) # +sf+ is a Rainbows::StreamFile object
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
192
|
+
case n = @_io.trysendfile(sf, sf.offset, sf.count)
|
193
|
+
when Integer
|
194
|
+
sf.offset += n
|
195
|
+
return if 0 == (sf.count -= n)
|
196
|
+
when :wait_writable
|
197
|
+
return enable_write_watcher
|
198
|
+
else
|
199
|
+
return
|
200
|
+
end while true
|
200
201
|
end
|
201
202
|
else
|
202
203
|
def defer_file(status, headers, body, alive, io, st)
|
@@ -205,7 +206,7 @@ class Rainbows::Coolio::Client < Coolio::IO
|
|
205
206
|
end
|
206
207
|
|
207
208
|
def stream_file_chunk(body)
|
208
|
-
|
209
|
+
buf = body.to_io.read(0x4000) and write(buf)
|
209
210
|
end
|
210
211
|
end
|
211
212
|
|
@@ -183,15 +183,16 @@ module Rainbows::Epoll::Client
|
|
183
183
|
|
184
184
|
# returns +nil+ on EOF, :wait_writable if the client blocks
|
185
185
|
def stream_file(sf) # +sf+ is a Rainbows::StreamFile object
|
186
|
-
|
187
|
-
|
186
|
+
case n = trysendfile(sf, sf.offset, sf.count)
|
187
|
+
when Integer
|
188
|
+
sf.offset += n
|
188
189
|
0 == (sf.count -= n) and return sf.close
|
189
|
-
|
190
|
-
return :wait_writable
|
190
|
+
else
|
191
|
+
return n # :wait_writable or nil
|
192
|
+
end while true
|
191
193
|
rescue
|
192
194
|
sf.close
|
193
195
|
raise
|
194
|
-
end while true
|
195
196
|
end
|
196
197
|
|
197
198
|
def defer_file_stream(offset, count, io, body)
|
data/lib/rainbows/fiber/body.rb
CHANGED
@@ -5,19 +5,20 @@
|
|
5
5
|
# this is meant to be included _after_ Rainbows::Response::Body
|
6
6
|
module Rainbows::Fiber::Body # :nodoc:
|
7
7
|
|
8
|
-
# the sendfile 1.
|
9
|
-
if IO.method_defined?(:
|
8
|
+
# the sendfile 1.1.0+ gem includes IO#trysendfile
|
9
|
+
if IO.method_defined?(:trysendfile)
|
10
10
|
def write_body_file(body, range)
|
11
11
|
sock, n, body = to_io, nil, body_to_io(body)
|
12
12
|
offset, count = range ? range : [ 0, body.stat.size ]
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
case n = sock.trysendfile(body, offset, count)
|
14
|
+
when Integer
|
15
|
+
offset += n
|
16
|
+
return if 0 == (count -= n)
|
17
|
+
when :wait_writable
|
16
18
|
kgio_wait_writable
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end while (count -= n) > 0
|
19
|
+
else # nil
|
20
|
+
return
|
21
|
+
end while true
|
21
22
|
ensure
|
22
23
|
close_if_private(body)
|
23
24
|
end
|
data/lib/rainbows/response.rb
CHANGED
@@ -67,7 +67,7 @@ module Rainbows::Response
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# generic response writer, used for most dynamically-generated responses
|
70
|
-
# and also when IO.copy_stream and/or IO#
|
70
|
+
# and also when IO.copy_stream and/or IO#trysendfile is unavailable
|
71
71
|
def write_response(status, headers, body, alive)
|
72
72
|
write_headers(status, headers, alive)
|
73
73
|
write_body_each(body)
|
@@ -77,7 +77,7 @@ module Rainbows::Response
|
|
77
77
|
end
|
78
78
|
include Each
|
79
79
|
|
80
|
-
if IO.method_defined?(:
|
80
|
+
if IO.method_defined?(:trysendfile)
|
81
81
|
module Sendfile
|
82
82
|
def write_body_file(body, range)
|
83
83
|
io = body_to_io(body)
|
@@ -90,7 +90,7 @@ module Rainbows::Response
|
|
90
90
|
end
|
91
91
|
|
92
92
|
if IO.respond_to?(:copy_stream)
|
93
|
-
unless IO.method_defined?(:
|
93
|
+
unless IO.method_defined?(:trysendfile)
|
94
94
|
module CopyStream
|
95
95
|
def write_body_file(body, range)
|
96
96
|
range ? IO.copy_stream(body, self, range[1], range[0]) :
|
@@ -111,7 +111,7 @@ module Rainbows::Response
|
|
111
111
|
alias write_body_stream write_body_each
|
112
112
|
end # ! IO.respond_to?(:copy_stream)
|
113
113
|
|
114
|
-
if IO.method_defined?(:
|
114
|
+
if IO.method_defined?(:trysendfile) || IO.respond_to?(:copy_stream)
|
115
115
|
HTTP_RANGE = 'HTTP_RANGE'
|
116
116
|
Content_Range = 'Content-Range'.freeze
|
117
117
|
|
@@ -181,5 +181,5 @@ module Rainbows::Response
|
|
181
181
|
end
|
182
182
|
end
|
183
183
|
include ToPath
|
184
|
-
end # IO.respond_to?(:copy_stream) || IO.method_defined?(:
|
184
|
+
end # IO.respond_to?(:copy_stream) || IO.method_defined?(:trysendfile)
|
185
185
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
# :enddoc:
|
3
3
|
module Rainbows::Revactor::Client::Methods
|
4
|
-
if IO.method_defined?(:
|
4
|
+
if IO.method_defined?(:trysendfile)
|
5
5
|
def write_body_file(body, range)
|
6
6
|
body, client = body_to_io(body), @client
|
7
7
|
sock = @client.instance_variable_get(:@_io)
|
@@ -9,9 +9,11 @@ module Rainbows::Revactor::Client::Methods
|
|
9
9
|
write_complete = T[:"#{pfx}_write_complete", client]
|
10
10
|
closed = T[:"#{pfx}_closed", client]
|
11
11
|
offset, count = range ? range : [ 0, body.stat.size ]
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
case n = sock.trysendfile(body, offset, count)
|
13
|
+
when Integer
|
14
|
+
offset += n
|
15
|
+
return if 0 == (count -= n)
|
16
|
+
when :wait_writable
|
15
17
|
# The @_write_buffer is empty at this point, trigger the
|
16
18
|
# on_readable method which in turn triggers on_write_complete
|
17
19
|
# even though nothing was written
|
@@ -21,10 +23,9 @@ module Rainbows::Revactor::Client::Methods
|
|
21
23
|
filter.when(write_complete) {}
|
22
24
|
filter.when(closed) { raise Errno::EPIPE }
|
23
25
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end while (count -= n) > 0
|
26
|
+
else # nil
|
27
|
+
return
|
28
|
+
end while true
|
28
29
|
ensure
|
29
30
|
close_if_private(body)
|
30
31
|
end
|
data/lib/rainbows/stream_file.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
# :enddoc:
|
3
3
|
|
4
|
-
# Used to keep track of file offsets in IO#
|
4
|
+
# Used to keep track of file offsets in IO#trysendfile + evented
|
5
5
|
# models. We always maintain our own file offsets in userspace because
|
6
6
|
# because sendfile() implementations offer pread()-like idempotency for
|
7
7
|
# concurrency (multiple clients can read the same underlying file handle).
|
@@ -18,7 +18,7 @@ class Rainbows::WriterThreadPool::Client < Struct.new(:to_io, :q)
|
|
18
18
|
}
|
19
19
|
end
|
20
20
|
|
21
|
-
if IO.respond_to?(:copy_stream) || IO.method_defined?(:
|
21
|
+
if IO.respond_to?(:copy_stream) || IO.method_defined?(:trysendfile)
|
22
22
|
def write_response(status, headers, body, alive)
|
23
23
|
if body.respond_to?(:close)
|
24
24
|
write_response_close(status, headers, body, alive)
|
@@ -21,7 +21,7 @@ class Rainbows::WriterThreadSpawn::Client < Struct.new(:to_io, :q, :thr)
|
|
21
21
|
}
|
22
22
|
end
|
23
23
|
|
24
|
-
if IO.respond_to?(:copy_stream) || IO.method_defined?(:
|
24
|
+
if IO.respond_to?(:copy_stream) || IO.method_defined?(:trysendfile)
|
25
25
|
def write_response(status, headers, body, alive)
|
26
26
|
self.q ||= queue_writer
|
27
27
|
if body.respond_to?(:close)
|
data/rainbows.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_dependency(%q<rack>, ['~> 1.1'])
|
26
26
|
|
27
27
|
# we need Unicorn for the HTTP parser and process management
|
28
|
-
s.add_dependency(%q<unicorn>, ["~> 3.
|
28
|
+
s.add_dependency(%q<unicorn>, ["~> 3.5"])
|
29
29
|
s.add_development_dependency(%q<isolate>, "~> 3.0.0")
|
30
30
|
s.add_development_dependency(%q<wrongdoc>, "~> 1.5")
|
31
31
|
|
data/t/cramp/rainsocket.ru
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# based on examples/rainsocket.ru git://github.com/lifo/cramp
|
2
2
|
# Rack::Lint does not like async + EM stuff, so disable it:
|
3
3
|
#\ -E deployment
|
4
|
-
require 'cramp
|
4
|
+
require 'cramp'
|
5
5
|
|
6
|
-
Cramp::
|
6
|
+
Cramp::Websocket.backend = :rainbows
|
7
7
|
|
8
|
-
class WelcomeController < Cramp::
|
8
|
+
class WelcomeController < Cramp::Websocket
|
9
9
|
periodic_timer :send_hello_world, :every => 2
|
10
10
|
on_data :received_data
|
11
11
|
|
data/t/cramp/streaming.ru
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
# Rack::Lint does not like async + EM stuff, so disable it:
|
5
5
|
#\ -E deployment
|
6
6
|
|
7
|
-
require 'cramp
|
7
|
+
require 'cramp'
|
8
8
|
|
9
|
-
class StreamController < Cramp::
|
9
|
+
class StreamController < Cramp::Action
|
10
10
|
periodic_timer :send_data, :every => 1
|
11
11
|
periodic_timer :check_limit, :every => 2
|
12
12
|
|
data/t/test_isolate.rb
CHANGED
@@ -16,16 +16,17 @@ $stdout.reopen($stderr)
|
|
16
16
|
lock = File.open(__FILE__, "rb")
|
17
17
|
lock.flock(File::LOCK_EX)
|
18
18
|
Isolate.now!(opts) do
|
19
|
-
gem 'unicorn', '3.
|
20
|
-
gem 'kcar', '0.
|
19
|
+
gem 'unicorn', '3.5.0'
|
20
|
+
gem 'kcar', '0.2.0'
|
21
21
|
gem 'raindrops', '0.4.1'
|
22
22
|
|
23
23
|
if engine == "ruby"
|
24
|
-
gem 'sendfile', '1.
|
24
|
+
gem 'sendfile', '1.1.0' # next Rubinius should support this
|
25
25
|
gem 'cool.io', '1.0.0'
|
26
26
|
|
27
27
|
gem 'eventmachine', '0.12.10'
|
28
|
-
gem '
|
28
|
+
gem 'sinatra', '1.2.0'
|
29
|
+
gem 'async_sinatra', '0.5.0'
|
29
30
|
|
30
31
|
gem 'neverblock', '0.1.6.2'
|
31
32
|
end
|
@@ -35,7 +36,7 @@ Isolate.now!(opts) do
|
|
35
36
|
gem 'rack-fiber_pool', '0.9.1'
|
36
37
|
end
|
37
38
|
|
38
|
-
gem 'sleepy_penguin', '
|
39
|
+
gem 'sleepy_penguin', '2.0.0' if RUBY_PLATFORM =~ /linux/
|
39
40
|
end
|
40
41
|
|
41
42
|
$stdout.reopen(old_out)
|
data/t/test_isolate_cramp.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rainbows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 3
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 3.2.0
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Rainbows! hackers
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-03-15 00:00:00 +00:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +26,10 @@ dependencies:
|
|
21
26
|
requirements:
|
22
27
|
- - ~>
|
23
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 1
|
24
33
|
version: "1.1"
|
25
34
|
type: :runtime
|
26
35
|
version_requirements: *id001
|
@@ -32,7 +41,11 @@ dependencies:
|
|
32
41
|
requirements:
|
33
42
|
- - ~>
|
34
43
|
- !ruby/object:Gem::Version
|
35
|
-
|
44
|
+
hash: 13
|
45
|
+
segments:
|
46
|
+
- 3
|
47
|
+
- 5
|
48
|
+
version: "3.5"
|
36
49
|
type: :runtime
|
37
50
|
version_requirements: *id002
|
38
51
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +56,11 @@ dependencies:
|
|
43
56
|
requirements:
|
44
57
|
- - ~>
|
45
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 7
|
60
|
+
segments:
|
61
|
+
- 3
|
62
|
+
- 0
|
63
|
+
- 0
|
46
64
|
version: 3.0.0
|
47
65
|
type: :development
|
48
66
|
version_requirements: *id003
|
@@ -54,6 +72,10 @@ dependencies:
|
|
54
72
|
requirements:
|
55
73
|
- - ~>
|
56
74
|
- !ruby/object:Gem::Version
|
75
|
+
hash: 5
|
76
|
+
segments:
|
77
|
+
- 1
|
78
|
+
- 5
|
57
79
|
version: "1.5"
|
58
80
|
type: :development
|
59
81
|
version_requirements: *id004
|
@@ -463,17 +485,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
463
485
|
requirements:
|
464
486
|
- - ">="
|
465
487
|
- !ruby/object:Gem::Version
|
488
|
+
hash: 3
|
489
|
+
segments:
|
490
|
+
- 0
|
466
491
|
version: "0"
|
467
492
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
468
493
|
none: false
|
469
494
|
requirements:
|
470
495
|
- - ">="
|
471
496
|
- !ruby/object:Gem::Version
|
497
|
+
hash: 3
|
498
|
+
segments:
|
499
|
+
- 0
|
472
500
|
version: "0"
|
473
501
|
requirements: []
|
474
502
|
|
475
503
|
rubyforge_project: rainbows
|
476
|
-
rubygems_version: 1.
|
504
|
+
rubygems_version: 1.6.1
|
477
505
|
signing_key:
|
478
506
|
specification_version: 3
|
479
507
|
summary: "- Unicorn for sleepy apps and slow clients"
|