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.
@@ -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
- BOSH, and Web Sockets possible
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
@@ -1,6 +1,6 @@
1
- % rainbows(1) Unicorn User Manual
2
- % The Unicorn Community <mongrel-unicorn@rubyforge.org>
3
- % September 15, 2009
1
+ % rainbows(1) Rainbows! User Manual
2
+ % Rainbows! Hackers <rainbows-talk@rubyforge.org>
3
+ % December 3, 2009
4
4
 
5
5
  # NAME
6
6
 
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.8.0.GIT
4
+ DEF_VER=v0.9.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.6.0
61
+ SINCE = 0.8.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/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
- * HTML 5 Web Sockets
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 :Revactor
120
- worker_connections 400
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
- content({:type => 'text'}, tag[:body])
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
@@ -9,6 +9,8 @@ care about.
9
9
 
10
10
  * EventMachine.spawn - should be like Revactor, maybe?
11
11
 
12
+ * EventMachine deferrables
13
+
12
14
  * conditional app.deferred?(env) support
13
15
  Merb uses it, some other servers support it
14
16
 
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 => 10,
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
@@ -43,6 +43,7 @@ module Rainbows
43
43
  buf << client.readpartial(CHUNK_SIZE)
44
44
  end
45
45
 
46
+ env[CLIENT_IO] = client
46
47
  env[RACK_INPUT] = 0 == hp.content_length ?
47
48
  HttpRequest::NULL_IO :
48
49
  Unicorn::TeeInput.new(client, env, hp, buf)
@@ -3,7 +3,7 @@
3
3
  module Rainbows
4
4
 
5
5
  module Const
6
- RAINBOWS_VERSION = '0.8.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
@@ -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
@@ -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] = Client.new(sig, io)
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 "EventMachine: epoll=#{EM.epoll?} kqueue=#{EM.kqueue?}"
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
- EvCore.setup(Client)
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 { |client| Client === client and client.quit }
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
@@ -82,6 +82,7 @@ module Rainbows
82
82
  buf << (client.read_timeout or return)
83
83
  end
84
84
 
85
+ env[CLIENT_IO] = client
85
86
  env[RACK_INPUT] = 0 == hp.content_length ?
86
87
  HttpRequest::NULL_IO : TeeInput.new(client, env, hp, buf)
87
88
  env[REMOTE_ADDR] = remote_addr
@@ -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
- Const::RACK_DEFAULTS['rack.multithread'] = !!(/Thread/ =~ model.to_s)
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
@@ -34,12 +34,14 @@ module Rainbows
34
34
  G.server.extend(Core)
35
35
  end
36
36
 
37
- module Client
38
-
37
+ module Core
39
38
  def self.setup
40
- const_set(:POOL, ::NB::Pool::FiberPool.new(O[:pool_size]))
41
- Rainbows.const_get(O[:backend]).const_get(:Client).module_eval do
42
- include Rainbows::NeverBlock::Client
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
- Client.setup
65
+ Core.setup
64
66
  logger.info "NeverBlock/#{O[:backend]} pool_size=#{O[:pool_size]}"
65
67
  end
66
68
  end
@@ -0,0 +1,6 @@
1
+ module Rainbows
2
+ module NeverBlock
3
+ class Client < Rainbows::EventMachine::Client
4
+ end
5
+ end
6
+ end
@@ -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
- io = new(io, client, do_chunk, body).attach(LOOP)
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
@@ -1,10 +1,6 @@
1
1
  # -*- encoding: binary -*-
2
2
  require 'rainbows/rev'
3
3
 
4
- RUBY_VERSION =~ %r{\A1\.8} && ::Rev::VERSION < "0.3.2" and
5
- warn "Rainbows::RevThreadSpawn + Rev (< 0.3.2)" \
6
- " does not work well under Ruby 1.8"
7
-
8
4
  module Rainbows
9
5
 
10
6
  module Rev
@@ -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
 
@@ -22,7 +22,7 @@ module Rainbows
22
22
  module RevThreadPool
23
23
 
24
24
  DEFAULTS = {
25
- :pool_size => 10, # same default size as ThreadPool (w/o Rev)
25
+ :pool_size => 20, # same default size as ThreadPool (w/o Rev)
26
26
  }
27
27
 
28
28
  def self.setup
@@ -49,6 +49,7 @@ module Rainbows
49
49
  buf << client.read(*rd_args)
50
50
  end
51
51
 
52
+ env[Const::CLIENT_IO] = client
52
53
  env[Const::RACK_INPUT] = 0 == hp.content_length ?
53
54
  HttpRequest::NULL_IO :
54
55
  Rainbows::Revactor::TeeInput.new(client, env, hp, buf)
@@ -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.8.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-02 00:00:00 +00:00
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