rainbows 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|