rainbows 0.8.0 → 0.9.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/Documentation/comparison.haml +14 -1
- data/Documentation/rainbows.1.txt +3 -3
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +1 -1
- data/README +6 -4
- data/Rakefile +32 -1
- data/TODO +2 -0
- data/lib/rainbows.rb +2 -1
- data/lib/rainbows/base.rb +1 -0
- data/lib/rainbows/const.rb +7 -1
- data/lib/rainbows/error.rb +2 -1
- data/lib/rainbows/ev_core.rb +3 -1
- data/lib/rainbows/event_machine.rb +6 -7
- data/lib/rainbows/event_machine_defer.rb +59 -0
- data/lib/rainbows/fiber/base.rb +1 -0
- data/lib/rainbows/http_server.rb +6 -1
- data/lib/rainbows/never_block.rb +8 -6
- data/lib/rainbows/never_block/event_machine.rb +6 -0
- data/lib/rainbows/rev/core.rb +1 -2
- data/lib/rainbows/rev/deferred_response.rb +3 -5
- data/lib/rainbows/rev/master.rb +0 -4
- data/lib/rainbows/rev/thread.rb +3 -1
- data/lib/rainbows/rev_thread_pool.rb +1 -1
- data/lib/rainbows/revactor.rb +1 -0
- data/t/simple-http_EventMachineDefer.ru +11 -0
- metadata +7 -2
@@ -101,7 +101,7 @@
|
|
101
101
|
%li
|
102
102
|
rack.input streaming is what makes
|
103
103
|
%a(href="http://upr.bogomips.org/") upload progress,
|
104
|
-
|
104
|
+
and BOSH possible
|
105
105
|
%li
|
106
106
|
rack.input streaming is NOT compatible with current versions of nginx
|
107
107
|
or any proxy that fully buffers request bodies before proxying.
|
@@ -221,78 +221,91 @@
|
|
221
221
|
%th.lock
|
222
222
|
%a(href="http://rack.rubyforge.org/doc/Rack/Lock.html") Rack::Lock
|
223
223
|
%th.async async
|
224
|
+
%th.ws Web Sockets
|
224
225
|
%tr.comp_row
|
225
226
|
%td.mod Unicorn/Base
|
226
227
|
%td.devfd no-op
|
227
228
|
%td.app_pool no-op
|
228
229
|
%td.lock no-op
|
229
230
|
%td.async lots of RAM :P
|
231
|
+
%td.ws no
|
230
232
|
%tr.comp_row
|
231
233
|
%td.mod Revactor
|
232
234
|
%td.devfd no-op
|
233
235
|
%td.app_pool Yes
|
234
236
|
%td.lock No!
|
235
237
|
%td.async Revactor itself
|
238
|
+
%td.ws Sunshowers
|
236
239
|
%tr.comp_row
|
237
240
|
%td.mod ThreadPool
|
238
241
|
%td.devfd no-op
|
239
242
|
%td.app_pool Yes
|
240
243
|
%td.lock Yes
|
241
244
|
%td.async standard Ruby
|
245
|
+
%td.ws Sunshowers
|
242
246
|
%tr.comp_row
|
243
247
|
%td.mod Rev
|
244
248
|
%td.devfd Yes
|
245
249
|
%td.app_pool no-op
|
246
250
|
%td.lock no-op
|
247
251
|
%td.async DevFdResponse
|
252
|
+
%td.ws no
|
248
253
|
%tr.comp_row
|
249
254
|
%td.mod ThreadSpawn
|
250
255
|
%td.devfd no-op
|
251
256
|
%td.app_pool Yes
|
252
257
|
%td.lock Yes
|
253
258
|
%td.async standard Ruby
|
259
|
+
%td.ws Sunshowers
|
254
260
|
%tr.comp_row
|
255
261
|
%td.mod EventMachine
|
256
262
|
%td.devfd Yes
|
257
263
|
%td.app_pool no-op
|
258
264
|
%td.lock no-op
|
259
265
|
%td.async async_sinatra
|
266
|
+
%td.ws no
|
260
267
|
%tr.comp_row
|
261
268
|
%td.mod RevThreadSpawn
|
262
269
|
%td.devfd Yes
|
263
270
|
%td.app_pool Yes
|
264
271
|
%td.lock Dumb
|
265
272
|
%td.async standard Ruby
|
273
|
+
%td.ws no
|
266
274
|
%tr.comp_row
|
267
275
|
%td.mod FiberSpawn
|
268
276
|
%td.devfd Yes
|
269
277
|
%td.app_pool Yes
|
270
278
|
%td.lock No!
|
271
279
|
%td.async Rainbows::Fiber{::IO,.sleep}
|
280
|
+
%td.ws Sunshowers
|
272
281
|
%tr.comp_row
|
273
282
|
%td.mod FiberPool
|
274
283
|
%td.devfd Yes
|
275
284
|
%td.app_pool Yes
|
276
285
|
%td.lock No!
|
277
286
|
%td.async Rainbows::Fiber{::IO,.sleep}
|
287
|
+
%td.ws Sunshowers
|
278
288
|
%tr.comp_row
|
279
289
|
%td.mod ActorSpawn
|
280
290
|
%td.devfd no-op
|
281
291
|
%td.app_pool Yes
|
282
292
|
%td.lock Yes
|
283
293
|
%td.async standard Ruby
|
294
|
+
%td.ws Sunshowers
|
284
295
|
%tr.comp_row
|
285
296
|
%td.mod NeverBlock
|
286
297
|
%td.devfd Yes
|
287
298
|
%td.app_pool Yes*
|
288
299
|
%td.lock Yes*
|
289
300
|
%td.async NeverBlock, async_sinatra
|
301
|
+
%td.ws no
|
290
302
|
%tr.comp_row
|
291
303
|
%td.mod RevThreadPool
|
292
304
|
%td.devfd Yes
|
293
305
|
%td.app_pool Yes
|
294
306
|
%td.lock Dumb
|
295
307
|
%td.async standard Ruby
|
308
|
+
%td.ws no
|
296
309
|
|
297
310
|
%ul
|
298
311
|
%li
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
data/README
CHANGED
@@ -22,6 +22,7 @@ For network concurrency, models we currently support are:
|
|
22
22
|
* {FiberSpawn}[link:Rainbows/FiberSpawn.html]
|
23
23
|
* {FiberPool}[link:Rainbows/FiberPool.html]
|
24
24
|
* {NeverBlock}[link:Rainbows/NeverBlock.html]
|
25
|
+
* {RevThreadPool}[link:Rainbows/RevThreadPool.html]
|
25
26
|
|
26
27
|
We have {many more on the way}[link:TODO.html] for handling network
|
27
28
|
concurrency. Additionally, we also use multiple processes (managed by
|
@@ -57,6 +58,7 @@ network concurrency.
|
|
57
58
|
|
58
59
|
\Rainbows is mainly designed for the odd things Unicorn sucks at:
|
59
60
|
|
61
|
+
* Web Sockets (via {Sunshowers}[http://rainbows.rubyforge.org/sunshowers/])
|
60
62
|
* 3rd-party APIs (to services outside your control/LAN)
|
61
63
|
* OpenID consumers (to providers outside your control/LAN)
|
62
64
|
* Reverse proxy implementations with editing/censoring
|
@@ -66,8 +68,7 @@ network concurrency.
|
|
66
68
|
* HTTP server push
|
67
69
|
* Long polling
|
68
70
|
* Reverse AJAX
|
69
|
-
*
|
70
|
-
* real-time upload processing
|
71
|
+
* real-time upload processing (via {upr}[http://upr.bogomips.org/])
|
71
72
|
|
72
73
|
\Rainbows can also be used to service slow clients directly even with
|
73
74
|
fast applications.
|
@@ -115,9 +116,10 @@ command-line switch. \Rainbows! accepts all options found in
|
|
115
116
|
as well as the "\Rainbows!" block, so you can have the following in your
|
116
117
|
config file:
|
117
118
|
|
119
|
+
worker_processes 4 # assuming four CPU cores
|
118
120
|
Rainbows! do
|
119
|
-
use :
|
120
|
-
worker_connections
|
121
|
+
use :FiberSpawn
|
122
|
+
worker_connections 100
|
121
123
|
end
|
122
124
|
|
123
125
|
See the {Rainbows! configuration documentation}[link:Rainbows.html#M000001]
|
data/Rakefile
CHANGED
@@ -50,7 +50,9 @@ task :news_atom do
|
|
50
50
|
url = "#{cgit_url}/tag/?id=#{tag[:tag]}"
|
51
51
|
link! :rel => "alternate", :type => "text/html", :href =>url
|
52
52
|
id! url
|
53
|
-
|
53
|
+
message_only = tag[:body].split(/\n.+\(\d+\):\n {6}/s).first.strip
|
54
|
+
content({:type =>:text}, message_only)
|
55
|
+
content(:type =>:xhtml) { pre tag[:body] }
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -154,3 +156,32 @@ task :raa_update do
|
|
154
156
|
p res
|
155
157
|
puts res.body
|
156
158
|
end
|
159
|
+
|
160
|
+
desc "post to FM"
|
161
|
+
task :fm_update do
|
162
|
+
require 'tempfile'
|
163
|
+
require 'net/http'
|
164
|
+
require 'net/netrc'
|
165
|
+
require 'json'
|
166
|
+
version = ENV['VERSION'] or abort "VERSION= needed"
|
167
|
+
uri = URI.parse('http://freshmeat.net/projects/unicorn/releases.json')
|
168
|
+
rc = Net::Netrc.locate('unicorn-fm') or abort "~/.netrc not found"
|
169
|
+
api_token = rc.password
|
170
|
+
changelog = tags.find { |t| t[:tag] == "v#{version}" }[:body]
|
171
|
+
tmp = Tempfile.new('fm-changelog')
|
172
|
+
tmp.syswrite(changelog)
|
173
|
+
system(ENV["VISUAL"], tmp.path) or abort "#{ENV["VISUAL"]} failed: #$?"
|
174
|
+
changelog = File.read(tmp.path).strip
|
175
|
+
|
176
|
+
req = {
|
177
|
+
"auth_code" => api_token,
|
178
|
+
"release" => {
|
179
|
+
"tag_list" => "Stable",
|
180
|
+
"version" => version,
|
181
|
+
"changelog" => changelog,
|
182
|
+
},
|
183
|
+
}.to_json
|
184
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
185
|
+
p http.post(uri.path, req, {'Content-Type'=>'application/json'})
|
186
|
+
end
|
187
|
+
end
|
data/TODO
CHANGED
data/lib/rainbows.rb
CHANGED
@@ -77,11 +77,12 @@ module Rainbows
|
|
77
77
|
:Base => 1, # this one can't change
|
78
78
|
:Revactor => 50,
|
79
79
|
:ThreadSpawn => 30,
|
80
|
-
:ThreadPool =>
|
80
|
+
:ThreadPool => 20,
|
81
81
|
:Rev => 50,
|
82
82
|
:RevThreadSpawn => 50,
|
83
83
|
:RevThreadPool => 50,
|
84
84
|
:EventMachine => 50,
|
85
|
+
:EventMachineDefer => 50,
|
85
86
|
:FiberSpawn => 50,
|
86
87
|
:FiberPool => 50,
|
87
88
|
:ActorSpawn => 50,
|
data/lib/rainbows/base.rb
CHANGED
data/lib/rainbows/const.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Rainbows
|
4
4
|
|
5
5
|
module Const
|
6
|
-
RAINBOWS_VERSION = '0.
|
6
|
+
RAINBOWS_VERSION = '0.9.0'
|
7
7
|
|
8
8
|
include Unicorn::Const
|
9
9
|
|
@@ -19,5 +19,11 @@ module Rainbows
|
|
19
19
|
CONN_ALIVE = "Connection: keep-alive\r\n"
|
20
20
|
LOCALHOST = "127.0.0.1"
|
21
21
|
|
22
|
+
# client IO object that supports reading and writing directly
|
23
|
+
# without filtering it through the HTTP chunk parser.
|
24
|
+
# Maybe we can get this renamed to "rack.io" if it becomes part
|
25
|
+
# of the official spec, but for now it is "hack.io"
|
26
|
+
CLIENT_IO = "hack.io".freeze
|
27
|
+
|
22
28
|
end
|
23
29
|
end
|
data/lib/rainbows/error.rb
CHANGED
@@ -19,10 +19,11 @@ module Rainbows
|
|
19
19
|
|
20
20
|
def response(e)
|
21
21
|
case e
|
22
|
-
when EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
|
22
|
+
when EOFError, Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
|
23
23
|
# swallow error if client shuts down one end or disconnects
|
24
24
|
when Unicorn::HttpParserError
|
25
25
|
Const::ERROR_400_RESPONSE # try to tell the client they're bad
|
26
|
+
when IOError # HttpParserError is an IOError
|
26
27
|
else
|
27
28
|
app(e)
|
28
29
|
Const::ERROR_500_RESPONSE
|
data/lib/rainbows/ev_core.rb
CHANGED
@@ -8,6 +8,9 @@ module Rainbows
|
|
8
8
|
include Rainbows::Const
|
9
9
|
G = Rainbows::G
|
10
10
|
|
11
|
+
# Apps may return this Rack response: AsyncResponse = [ -1, {}, [] ]
|
12
|
+
ASYNC_CALLBACK = "async.callback".freeze
|
13
|
+
|
11
14
|
def self.setup(klass)
|
12
15
|
klass.const_set(:APP, G.server.app)
|
13
16
|
end
|
@@ -66,7 +69,6 @@ module Rainbows
|
|
66
69
|
if @hp.trailers(@env, @buf << data)
|
67
70
|
@input.rewind
|
68
71
|
app_call
|
69
|
-
@input.close if File === @input
|
70
72
|
end
|
71
73
|
end
|
72
74
|
rescue => e
|
@@ -35,9 +35,6 @@ module Rainbows
|
|
35
35
|
include Rainbows::EvCore
|
36
36
|
G = Rainbows::G
|
37
37
|
|
38
|
-
# Apps may return this Rack response: AsyncResponse = [ -1, {}, [] ]
|
39
|
-
ASYNC_CALLBACK = 'async.callback'.freeze
|
40
|
-
|
41
38
|
def initialize(io)
|
42
39
|
@_io = io
|
43
40
|
end
|
@@ -176,7 +173,7 @@ module Rainbows
|
|
176
173
|
return if CUR.size >= MAX
|
177
174
|
io = Rainbows.accept(@io) or return
|
178
175
|
sig = EM.attach_fd(io.fileno, false)
|
179
|
-
CUR[sig] =
|
176
|
+
CUR[sig] = CL.new(sig, io)
|
180
177
|
end
|
181
178
|
end
|
182
179
|
|
@@ -189,16 +186,18 @@ module Rainbows
|
|
189
186
|
# enable them both, should be non-fatal if not supported
|
190
187
|
EM.epoll
|
191
188
|
EM.kqueue
|
192
|
-
logger.info "
|
189
|
+
logger.info "#@use: epoll=#{EM.epoll?} kqueue=#{EM.kqueue?}"
|
190
|
+
client_class = Rainbows.const_get(@use).const_get(:Client)
|
193
191
|
Server.const_set(:MAX, worker_connections + LISTENERS.size)
|
194
|
-
|
192
|
+
Server.const_set(:CL, client_class)
|
193
|
+
EvCore.setup(client_class)
|
195
194
|
EM.run {
|
196
195
|
conns = EM.instance_variable_get(:@conns) or
|
197
196
|
raise RuntimeError, "EM @conns instance variable not accessible!"
|
198
197
|
Server.const_set(:CUR, conns)
|
199
198
|
EM.add_periodic_timer(1) do
|
200
199
|
unless G.tick
|
201
|
-
conns.each_value { |
|
200
|
+
conns.each_value { |c| client_class === c and c.quit }
|
202
201
|
EM.stop if conns.empty? && EM.reactor_running?
|
203
202
|
end
|
204
203
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- encoding: binary -*-
|
2
|
+
# :stopdoc:
|
3
|
+
# FIXME: fails many tests, experimental
|
4
|
+
require 'rainbows/event_machine'
|
5
|
+
|
6
|
+
module Rainbows
|
7
|
+
|
8
|
+
# This is currently highly experimental
|
9
|
+
module EventMachineDefer
|
10
|
+
include Rainbows::EventMachine
|
11
|
+
|
12
|
+
class Client < Rainbows::EventMachine::Client
|
13
|
+
undef_method :app_call
|
14
|
+
|
15
|
+
def defer_op
|
16
|
+
@env[RACK_INPUT] = @input
|
17
|
+
@env[REMOTE_ADDR] = @remote_addr
|
18
|
+
@env[ASYNC_CALLBACK] = method(:response_write)
|
19
|
+
catch(:async) { APP.call(@env.update(RACK_DEFAULTS)) }
|
20
|
+
rescue => e
|
21
|
+
handle_error(e)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def defer_callback(response)
|
26
|
+
# too tricky to support pipelining with :async since the
|
27
|
+
# second (pipelined) request could be a stuck behind a
|
28
|
+
# long-running async response
|
29
|
+
(response.nil? || -1 == response.first) and return @state = :close
|
30
|
+
|
31
|
+
resume
|
32
|
+
|
33
|
+
alive = @hp.keepalive? && G.alive
|
34
|
+
out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers?
|
35
|
+
response_write(response, out, alive)
|
36
|
+
if alive
|
37
|
+
@env.clear
|
38
|
+
@hp.reset
|
39
|
+
@state = :headers
|
40
|
+
if @hp.headers(@env, @buf)
|
41
|
+
EM.next_tick(method(:app_call))
|
42
|
+
else
|
43
|
+
set_comm_inactivity_timeout(G.kato)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
quit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def app_call
|
51
|
+
pause
|
52
|
+
set_comm_inactivity_timeout(0)
|
53
|
+
# defer_callback(defer_op)
|
54
|
+
EM.defer(method(:defer_op), method(:defer_callback))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/lib/rainbows/fiber/base.rb
CHANGED
data/lib/rainbows/http_server.rb
CHANGED
@@ -61,7 +61,12 @@ module Rainbows
|
|
61
61
|
end
|
62
62
|
mod.setup if mod.respond_to?(:setup)
|
63
63
|
Const::RACK_DEFAULTS['rainbows.model'] = @use = model.to_sym
|
64
|
-
|
64
|
+
|
65
|
+
Const::RACK_DEFAULTS['rack.multithread'] = case model.to_s
|
66
|
+
when /Thread/, "EventMachineDefer"; true
|
67
|
+
else false
|
68
|
+
end
|
69
|
+
|
65
70
|
case @use
|
66
71
|
when :Rev, :EventMachine, :NeverBlock
|
67
72
|
Const::RACK_DEFAULTS['rainbows.autochunk'] = true
|
data/lib/rainbows/never_block.rb
CHANGED
@@ -34,12 +34,14 @@ module Rainbows
|
|
34
34
|
G.server.extend(Core)
|
35
35
|
end
|
36
36
|
|
37
|
-
module
|
38
|
-
|
37
|
+
module Core
|
39
38
|
def self.setup
|
40
|
-
const_set(:POOL, ::NB::Pool::FiberPool.new(O[:pool_size]))
|
41
|
-
|
42
|
-
|
39
|
+
self.const_set(:POOL, ::NB::Pool::FiberPool.new(O[:pool_size]))
|
40
|
+
base = O[:backend].to_s.gsub!(/([a-z])([A-Z])/, '\1_\2').downcase!
|
41
|
+
require "rainbows/never_block/#{base}"
|
42
|
+
Rainbows::NeverBlock.const_get(:Client).class_eval do
|
43
|
+
self.superclass.const_set(:APP, G.server.app)
|
44
|
+
include Rainbows::NeverBlock::Core
|
43
45
|
alias _app_call app_call
|
44
46
|
undef_method :app_call
|
45
47
|
alias app_call nb_app_call
|
@@ -60,7 +62,7 @@ module Rainbows
|
|
60
62
|
module Core
|
61
63
|
def init_worker_process(worker)
|
62
64
|
super
|
63
|
-
|
65
|
+
Core.setup
|
64
66
|
logger.info "NeverBlock/#{O[:backend]} pool_size=#{O[:pool_size]}"
|
65
67
|
end
|
66
68
|
end
|
data/lib/rainbows/rev/core.rb
CHANGED
@@ -7,7 +7,6 @@ module Rainbows
|
|
7
7
|
module Rev
|
8
8
|
class Server < ::Rev::IO
|
9
9
|
G = Rainbows::G
|
10
|
-
LOOP = ::Rev::Loop.default
|
11
10
|
# CL and MAX will be defined in the corresponding worker loop
|
12
11
|
|
13
12
|
def on_readable
|
@@ -25,10 +24,10 @@ module Rainbows
|
|
25
24
|
def worker_loop(worker)
|
26
25
|
init_worker_process(worker)
|
27
26
|
mod = self.class.const_get(@use)
|
27
|
+
rloop = Server.const_set(:LOOP, ::Rev::Loop.default)
|
28
28
|
Server.const_set(:MAX, @worker_connections)
|
29
29
|
Server.const_set(:CL, mod.const_get(:Client))
|
30
30
|
EvCore.setup(EvCore)
|
31
|
-
rloop = ::Rev::Loop.default
|
32
31
|
Heartbeat.new(1, true).attach(rloop)
|
33
32
|
LISTENERS.map! { |s| Server.new(s).attach(rloop) }
|
34
33
|
rloop.run
|
@@ -10,10 +10,6 @@ module Rainbows
|
|
10
10
|
G = Rainbows::G
|
11
11
|
HH = Rack::Utils::HeaderHash
|
12
12
|
|
13
|
-
# we only want to attach to the Rev::Loop belonging to the
|
14
|
-
# main thread in Ruby 1.9
|
15
|
-
LOOP = ::Rev::Loop.default
|
16
|
-
|
17
13
|
def self.defer!(client, response, out)
|
18
14
|
body = response.last
|
19
15
|
headers = HH.new(response[1])
|
@@ -36,7 +32,9 @@ module Rainbows
|
|
36
32
|
out[0] = CONN_CLOSE
|
37
33
|
end
|
38
34
|
|
39
|
-
|
35
|
+
# we only want to attach to the Rev::Loop belonging to the
|
36
|
+
# main thread in Ruby 1.9
|
37
|
+
io = new(io, client, do_chunk, body).attach(Server::LOOP)
|
40
38
|
elsif st.file?
|
41
39
|
headers.delete('Transfer-Encoding')
|
42
40
|
headers['Content-Length'] ||= st.size.to_s
|
data/lib/rainbows/rev/master.rb
CHANGED
data/lib/rainbows/rev/thread.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
require 'thread'
|
3
3
|
require 'rainbows/rev/master'
|
4
4
|
|
5
|
+
RUBY_VERSION =~ %r{\A1\.8} && Rev::VERSION < "0.3.2" and
|
6
|
+
warn "Rev (< 0.3.2) and Threads do not mix well under Ruby 1.8"
|
7
|
+
|
5
8
|
module Rainbows
|
6
9
|
module Rev
|
7
10
|
|
@@ -11,7 +14,6 @@ module Rainbows
|
|
11
14
|
KATO.delete(self)
|
12
15
|
disable
|
13
16
|
@env[RACK_INPUT] = @input
|
14
|
-
@input = nil # not sure why, @input seems to get closed otherwise...
|
15
17
|
app_dispatch # must be implemented by subclass
|
16
18
|
end
|
17
19
|
|
data/lib/rainbows/revactor.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
use Rack::ContentLength
|
2
|
+
use Rack::ContentType
|
3
|
+
run lambda { |env|
|
4
|
+
if env['rack.multithread'] == true &&
|
5
|
+
EM.reactor_running? &&
|
6
|
+
env['rainbows.model'] == :EventMachineDefer
|
7
|
+
[ 200, {}, [ env.inspect << "\n" ] ]
|
8
|
+
else
|
9
|
+
raise "incorrect parameters"
|
10
|
+
end
|
11
|
+
}
|
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.
|
4
|
+
version: 0.9.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: 2009-12-
|
12
|
+
date: 2009-12-13 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -46,6 +46,7 @@ extra_rdoc_files:
|
|
46
46
|
- lib/rainbows/error.rb
|
47
47
|
- lib/rainbows/ev_core.rb
|
48
48
|
- lib/rainbows/event_machine.rb
|
49
|
+
- lib/rainbows/event_machine_defer.rb
|
49
50
|
- lib/rainbows/fiber.rb
|
50
51
|
- lib/rainbows/fiber/base.rb
|
51
52
|
- lib/rainbows/fiber/io.rb
|
@@ -55,6 +56,7 @@ extra_rdoc_files:
|
|
55
56
|
- lib/rainbows/http_response.rb
|
56
57
|
- lib/rainbows/http_server.rb
|
57
58
|
- lib/rainbows/never_block.rb
|
59
|
+
- lib/rainbows/never_block/event_machine.rb
|
58
60
|
- lib/rainbows/rev.rb
|
59
61
|
- lib/rainbows/rev/client.rb
|
60
62
|
- lib/rainbows/rev/core.rb
|
@@ -111,6 +113,7 @@ files:
|
|
111
113
|
- lib/rainbows/error.rb
|
112
114
|
- lib/rainbows/ev_core.rb
|
113
115
|
- lib/rainbows/event_machine.rb
|
116
|
+
- lib/rainbows/event_machine_defer.rb
|
114
117
|
- lib/rainbows/fiber.rb
|
115
118
|
- lib/rainbows/fiber/base.rb
|
116
119
|
- lib/rainbows/fiber/io.rb
|
@@ -120,6 +123,7 @@ files:
|
|
120
123
|
- lib/rainbows/http_response.rb
|
121
124
|
- lib/rainbows/http_server.rb
|
122
125
|
- lib/rainbows/never_block.rb
|
126
|
+
- lib/rainbows/never_block/event_machine.rb
|
123
127
|
- lib/rainbows/rev.rb
|
124
128
|
- lib/rainbows/rev/client.rb
|
125
129
|
- lib/rainbows/rev/core.rb
|
@@ -158,6 +162,7 @@ files:
|
|
158
162
|
- t/sha1.ru
|
159
163
|
- t/simple-http_Base.ru
|
160
164
|
- t/simple-http_EventMachine.ru
|
165
|
+
- t/simple-http_EventMachineDefer.ru
|
161
166
|
- t/simple-http_FiberPool.ru
|
162
167
|
- t/simple-http_FiberSpawn.ru
|
163
168
|
- t/simple-http_NeverBlock.ru
|