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