rainbows 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +1 -0
- data/Documentation/GNUmakefile +4 -1
- data/Documentation/comparison.css +6 -0
- data/Documentation/comparison.haml +297 -0
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +24 -17
- data/README +32 -28
- data/Summary +7 -0
- data/TODO +4 -6
- data/bin/rainbows +2 -2
- data/lib/rainbows.rb +33 -3
- data/lib/rainbows/actor_spawn.rb +29 -0
- data/lib/rainbows/app_pool.rb +17 -6
- data/lib/rainbows/base.rb +10 -13
- data/lib/rainbows/const.rb +1 -1
- data/lib/rainbows/dev_fd_response.rb +6 -0
- data/lib/rainbows/error.rb +34 -0
- data/lib/rainbows/ev_core.rb +3 -12
- data/lib/rainbows/event_machine.rb +7 -9
- data/lib/rainbows/fiber.rb +15 -0
- data/lib/rainbows/fiber/base.rb +112 -0
- data/lib/rainbows/fiber/io.rb +65 -0
- data/lib/rainbows/fiber/queue.rb +35 -0
- data/lib/rainbows/fiber_pool.rb +44 -0
- data/lib/rainbows/fiber_spawn.rb +34 -0
- data/lib/rainbows/http_server.rb +14 -1
- data/lib/rainbows/never_block.rb +69 -0
- data/lib/rainbows/rev.rb +7 -0
- data/lib/rainbows/rev/client.rb +9 -3
- data/lib/rainbows/rev/core.rb +2 -5
- data/lib/rainbows/rev/heartbeat.rb +5 -1
- data/lib/rainbows/rev_thread_spawn.rb +62 -60
- data/lib/rainbows/revactor.rb +22 -23
- data/lib/rainbows/thread_pool.rb +28 -26
- data/lib/rainbows/thread_spawn.rb +33 -33
- data/local.mk.sample +9 -7
- data/rainbows.gemspec +8 -2
- data/t/GNUmakefile +14 -7
- data/t/fork-sleep.ru +10 -0
- data/t/simple-http_FiberPool.ru +9 -0
- data/t/simple-http_FiberSpawn.ru +9 -0
- data/t/simple-http_NeverBlock.ru +11 -0
- data/t/sleep.ru +2 -0
- data/t/t0000-simple-http.sh +12 -1
- data/t/t0001-unix-http.sh +12 -1
- data/t/t0009-broken-app.sh +56 -0
- data/t/t0009.ru +13 -0
- data/t/t0010-keepalive-timeout-effective.sh +42 -0
- data/t/t0011-close-on-exec-set.sh +54 -0
- data/t/t0300-async_sinatra.sh +1 -1
- data/t/t9000-rack-app-pool.sh +1 -1
- data/t/t9000.ru +8 -5
- data/t/test-lib.sh +14 -4
- metadata +33 -5
- data/lib/rainbows/ev_thread_core.rb +0 -80
data/.document
CHANGED
data/Documentation/GNUmakefile
CHANGED
@@ -0,0 +1,297 @@
|
|
1
|
+
%h2 core features and compatibility
|
2
|
+
%br
|
3
|
+
%table.comp
|
4
|
+
%tr.comp_header
|
5
|
+
%th.mod module
|
6
|
+
%th.tee rack.input streaming
|
7
|
+
%th.r18 Ruby 1.8
|
8
|
+
%th.r19 Ruby 1.9
|
9
|
+
%th.rbx Rubinius
|
10
|
+
%th.slow slow clients
|
11
|
+
%tr.comp_base
|
12
|
+
%td.mod Unicorn/Base
|
13
|
+
%td.tee Yes
|
14
|
+
%td.r18 Yes
|
15
|
+
%td.r19 Yes
|
16
|
+
%td.rbx Yes
|
17
|
+
%td.slow No
|
18
|
+
%tr.comp_row
|
19
|
+
%td.mod Revactor
|
20
|
+
%td.tee Yes
|
21
|
+
%td.r18 No
|
22
|
+
%td.r19 Yes
|
23
|
+
%td.rbx No
|
24
|
+
%td.slow Yes
|
25
|
+
%tr.comp_row
|
26
|
+
%td.mod ThreadPool
|
27
|
+
%td.tee Yes
|
28
|
+
%td.r18 Yes
|
29
|
+
%td.r19 Yes
|
30
|
+
%td.rbx Yes
|
31
|
+
%td.slow OK
|
32
|
+
%tr.comp_row
|
33
|
+
%td.mod Rev
|
34
|
+
%td.tee No
|
35
|
+
%td.r18 Yes
|
36
|
+
%td.r19 Yes
|
37
|
+
%td.rbx No
|
38
|
+
%td.slow Yes
|
39
|
+
%tr.comp_row
|
40
|
+
%td.mod ThreadSpawn
|
41
|
+
%td.tee Yes
|
42
|
+
%td.r18 Yes
|
43
|
+
%td.r19 Yes
|
44
|
+
%td.rbx Yes
|
45
|
+
%td.slow OK
|
46
|
+
%tr.comp_row
|
47
|
+
%td.mod EventMachine
|
48
|
+
%td.tee No
|
49
|
+
%td.r18 Yes
|
50
|
+
%td.r19 Yes
|
51
|
+
%td.rbx No
|
52
|
+
%td.slow Yes
|
53
|
+
%tr.comp_row
|
54
|
+
%td.mod RevThreadSpawn
|
55
|
+
%td.tee No
|
56
|
+
%td.r18 Slow*
|
57
|
+
%td.r19 Yes
|
58
|
+
%td.rbx No
|
59
|
+
%td.slow Yes
|
60
|
+
%tr.comp_row
|
61
|
+
%td.mod FiberSpawn
|
62
|
+
%td.tee Yes
|
63
|
+
%td.r18 No
|
64
|
+
%td.r19 Yes
|
65
|
+
%td.rbx No
|
66
|
+
%td.slow Yes
|
67
|
+
%tr.comp_row
|
68
|
+
%td.mod FiberPool
|
69
|
+
%td.tee Yes
|
70
|
+
%td.r18 No
|
71
|
+
%td.r19 Yes
|
72
|
+
%td.rbx No
|
73
|
+
%td.slow Yes
|
74
|
+
%tr.comp_base
|
75
|
+
%td.mod ActorSpawn
|
76
|
+
%td.tee Yes
|
77
|
+
%td.r18 Not yet
|
78
|
+
%td.r19 No
|
79
|
+
%td.rbx Yes
|
80
|
+
%td.slow Yes
|
81
|
+
%tr.comp_base
|
82
|
+
%td.mod NeverBlock
|
83
|
+
%td.tee No
|
84
|
+
%td.r18 Yes
|
85
|
+
%td.r19 Yes
|
86
|
+
%td.rbx No
|
87
|
+
%td.slow Yes
|
88
|
+
%ul
|
89
|
+
%li
|
90
|
+
RevThreadSpawn + 1.8 performance is being improved, follow
|
91
|
+
the
|
92
|
+
%a(href="http://rubyforge.org/mailman/listinfo/rev-talk")
|
93
|
+
rev-talk mailing list
|
94
|
+
for details.
|
95
|
+
%li
|
96
|
+
waiting on Rubinius for better signal handling
|
97
|
+
%li
|
98
|
+
rack.input streaming is what makes
|
99
|
+
%a(href="http://upr.bogomips.org/") upload progress,
|
100
|
+
BOSH, and Web Sockets possible
|
101
|
+
%li
|
102
|
+
rack.input streaming is NOT compatible with current versions of nginx
|
103
|
+
or any proxy that fully buffers request bodies before proxying.
|
104
|
+
Keep in mind request body buffering in nginx is a good thing in all
|
105
|
+
other cases where rack.input streaming is not needed.
|
106
|
+
|
107
|
+
%h2 application requirements
|
108
|
+
%br
|
109
|
+
%table.comp
|
110
|
+
%tr.comp_header
|
111
|
+
%th.mod module
|
112
|
+
%th.slowio slow I/O (backend, not client)
|
113
|
+
%th.thr thread safety
|
114
|
+
%th.reent single thread reentrant
|
115
|
+
%tr.comp_base
|
116
|
+
%td.mod Unicorn/Base
|
117
|
+
%td.slowio avoid
|
118
|
+
%td.thr No
|
119
|
+
%td.reent No
|
120
|
+
%tr.comp_row
|
121
|
+
%td.mod Revactor
|
122
|
+
%td.slowio
|
123
|
+
%a(href="http://rev.rubyforge.org/")Rev,
|
124
|
+
%a(href="http://revactor.org/")Revactor,
|
125
|
+
%b
|
126
|
+
not
|
127
|
+
%a(href="Rainbows/Fiber/IO.html")Fiber::IO
|
128
|
+
%td.thr No
|
129
|
+
%td.reent Yes
|
130
|
+
%tr.comp_row
|
131
|
+
%td.mod ThreadPool
|
132
|
+
%td.slowio thread-safe Ruby
|
133
|
+
%td.thr Yes
|
134
|
+
%td.reent No
|
135
|
+
%tr.comp_row
|
136
|
+
%td.mod Rev
|
137
|
+
%td.slowio
|
138
|
+
%a(href="http://rev.rubyforge.org/") Rev
|
139
|
+
%td.thr No
|
140
|
+
%td.reent No
|
141
|
+
%tr.comp_row
|
142
|
+
%td.mod ThreadSpawn
|
143
|
+
%td.slowio thread-safe Ruby
|
144
|
+
%td.thr Yes
|
145
|
+
%td.reent No
|
146
|
+
%tr.comp_row
|
147
|
+
%td.mod EventMachine
|
148
|
+
%td.slowio
|
149
|
+
%a(href="http://rubyeventmachine.com") EventMachine
|
150
|
+
%td.thr No
|
151
|
+
%td.reent No
|
152
|
+
%tr.comp_row
|
153
|
+
%td.mod RevThreadSpawn
|
154
|
+
%td.slowio
|
155
|
+
thread-safe Ruby,
|
156
|
+
%a(href="http://rev.rubyforge.org/") Rev
|
157
|
+
%td.thr Yes
|
158
|
+
%td.reent No
|
159
|
+
%tr.comp_row
|
160
|
+
%td.mod FiberSpawn
|
161
|
+
%td.slowio
|
162
|
+
%a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
|
163
|
+
%td.thr No
|
164
|
+
%td.reent Yes
|
165
|
+
%tr.comp_row
|
166
|
+
%td.mod FiberPool
|
167
|
+
%td.slowio
|
168
|
+
%a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
|
169
|
+
%td.thr No
|
170
|
+
%td.reent Yes
|
171
|
+
%tr.comp_base
|
172
|
+
%td.mod ActorSpawn
|
173
|
+
%td.slowio thread-safe Ruby
|
174
|
+
%td.thr Yes
|
175
|
+
%td.reent Yes
|
176
|
+
%tr.comp_base
|
177
|
+
%td.mod NeverBlock
|
178
|
+
%td.slowio
|
179
|
+
%a(href="http://www.espace.com.eg/neverblock") NeverBlock,
|
180
|
+
%a(href="http://rubyeventmachine.com") EventMachine
|
181
|
+
%td.thr No
|
182
|
+
%td.reent Yes
|
183
|
+
|
184
|
+
%ul
|
185
|
+
%li
|
186
|
+
Requirements for single thread reentrancy are loose in that there is
|
187
|
+
no risk of race conditions and potentially mutually exclusive to
|
188
|
+
thread-safety. In the case where a Fiber yields while holding a
|
189
|
+
resource and another Fiber attempting to acquire it may raise
|
190
|
+
an error or worse, deadlock the entire process.
|
191
|
+
%li
|
192
|
+
Slow I/O means anything that can block/stall on sockets including
|
193
|
+
3rd-party APIs (OpenID providers included) or slow database queries.
|
194
|
+
Properly run Memcached (within the same LAN) is fast and not a blocker.
|
195
|
+
Slow I/O on POSIX filesystems only includes a few operations, namely
|
196
|
+
on UNIX domain sockets and named pipes. Nearly all other operations
|
197
|
+
on POSIX filesystems can be considered "fast", or at least
|
198
|
+
uninterruptible.
|
199
|
+
|
200
|
+
%h2 middlewares and frameworks
|
201
|
+
%br
|
202
|
+
|
203
|
+
%table.comp
|
204
|
+
%tr.comp_header
|
205
|
+
%th.mod model
|
206
|
+
%th.devfd
|
207
|
+
%a(href="Rainbows/DevFdResponse.html") DevFdResponse
|
208
|
+
%th.app_pool
|
209
|
+
%a(href="Rainbows/AppPool.html") AppPool
|
210
|
+
%th.lock
|
211
|
+
%a(href="http://rack.rubyforge.org/doc/Rack/Lock.html") Rack::Lock
|
212
|
+
%th.async async
|
213
|
+
%tr.comp_row
|
214
|
+
%td.mod Unicorn/Base
|
215
|
+
%td.devfd no-op
|
216
|
+
%td.app_pool no-op
|
217
|
+
%td.lock no-op
|
218
|
+
%td.async lots of RAM :P
|
219
|
+
%tr.comp_row
|
220
|
+
%td.mod Revactor
|
221
|
+
%td.devfd no-op
|
222
|
+
%td.app_pool Yes
|
223
|
+
%td.lock No!
|
224
|
+
%td.async Revactor itself
|
225
|
+
%tr.comp_row
|
226
|
+
%td.mod ThreadPool
|
227
|
+
%td.devfd no-op
|
228
|
+
%td.app_pool Yes
|
229
|
+
%td.lock Yes
|
230
|
+
%td.async standard Ruby
|
231
|
+
%tr.comp_row
|
232
|
+
%td.mod Rev
|
233
|
+
%td.devfd Yes
|
234
|
+
%td.app_pool no-op
|
235
|
+
%td.lock no-op
|
236
|
+
%td.async DevFdResponse
|
237
|
+
%tr.comp_row
|
238
|
+
%td.mod ThreadSpawn
|
239
|
+
%td.devfd no-op
|
240
|
+
%td.app_pool Yes
|
241
|
+
%td.lock Yes
|
242
|
+
%td.async standard Ruby
|
243
|
+
%tr.comp_row
|
244
|
+
%td.mod EventMachine
|
245
|
+
%td.devfd Yes
|
246
|
+
%td.app_pool no-op
|
247
|
+
%td.lock no-op
|
248
|
+
%td.async async_sinatra
|
249
|
+
%tr.comp_row
|
250
|
+
%td.mod RevThreadSpawn
|
251
|
+
%td.devfd Yes
|
252
|
+
%td.app_pool Yes
|
253
|
+
%td.lock Dumb
|
254
|
+
%td.async standard Ruby
|
255
|
+
%tr.comp_row
|
256
|
+
%td.mod FiberSpawn
|
257
|
+
%td.devfd Yes
|
258
|
+
%td.app_pool Yes
|
259
|
+
%td.lock No!
|
260
|
+
%td.async Rainbows::Fiber{::IO,.sleep}
|
261
|
+
%tr.comp_row
|
262
|
+
%td.mod FiberPool
|
263
|
+
%td.devfd Yes
|
264
|
+
%td.app_pool Yes
|
265
|
+
%td.lock No!
|
266
|
+
%td.async Rainbows::Fiber{::IO,.sleep}
|
267
|
+
%tr.comp_row
|
268
|
+
%td.mod ActorSpawn
|
269
|
+
%td.devfd no-op
|
270
|
+
%td.app_pool Yes
|
271
|
+
%td.lock Yes
|
272
|
+
%td.async standard Ruby
|
273
|
+
%tr.comp_row
|
274
|
+
%td.mod NeverBlock
|
275
|
+
%td.devfd Yes
|
276
|
+
%td.app_pool Yes*
|
277
|
+
%td.lock Yes*
|
278
|
+
%td.async NeverBlock, async_sinatra
|
279
|
+
|
280
|
+
%ul
|
281
|
+
%li
|
282
|
+
"No!" means it's fundamentally incompatible, use an
|
283
|
+
%a(href="Rainbows/AppPool.html") AppPool
|
284
|
+
%b :size
|
285
|
+
of one instead.
|
286
|
+
%li
|
287
|
+
NeverBlock also supports a :pool_size option which is one less
|
288
|
+
layer of complexity than using AppPool.
|
289
|
+
%li
|
290
|
+
NeverBlock can neuter the Mutex class so Rack::Lock effectively
|
291
|
+
becomes a no-op with:
|
292
|
+
%br
|
293
|
+
%code require "never_block/frameworks/rails"
|
294
|
+
(before Rails is loaded)
|
295
|
+
%li
|
296
|
+
Everything that's DevFdResponse-compatible can use it for passing
|
297
|
+
async responses through
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -1,19 +1,13 @@
|
|
1
|
-
# use GNU Make to run tests in parallel, and without depending on
|
1
|
+
# use GNU Make to run tests in parallel, and without depending on RubyGems
|
2
2
|
all::
|
3
3
|
RUBY = ruby
|
4
|
-
|
4
|
+
RAKE = rake
|
5
5
|
GIT_URL = git://git.bogomips.org/rainbows.git
|
6
6
|
|
7
7
|
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
8
8
|
@./GIT-VERSION-GEN
|
9
9
|
-include GIT-VERSION-FILE
|
10
10
|
-include local.mk
|
11
|
-
ifdef ruby
|
12
|
-
ifeq ($(RUBY),ruby)
|
13
|
-
$(warning ruby variable is deprecated, use RUBY instead)
|
14
|
-
RUBY = $(ruby)
|
15
|
-
endif
|
16
|
-
endif
|
17
11
|
ifeq ($(DLEXT),) # "so" for Linux
|
18
12
|
DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
|
19
13
|
endif
|
@@ -61,13 +55,16 @@ manifest: $(pkg_extra) man
|
|
61
55
|
$(RM) $@+
|
62
56
|
|
63
57
|
NEWS: GIT-VERSION-FILE
|
64
|
-
$(
|
58
|
+
$(RAKE) -s news_rdoc > $@+
|
65
59
|
mv $@+ $@
|
66
60
|
|
67
|
-
SINCE = 0.
|
68
|
-
ChangeLog:
|
61
|
+
SINCE = 0.6.0
|
62
|
+
ChangeLog: LOG_VERSION = \
|
63
|
+
$(shell git rev-parse -q "$(GIT_VERSION)" >/dev/null 2>&1 && \
|
64
|
+
echo $(GIT_VERSION) || git describe)
|
65
|
+
ChangeLog: log_range = v$(SINCE)..$(LOG_VERSION)
|
69
66
|
ChangeLog: GIT-VERSION-FILE
|
70
|
-
@echo "ChangeLog from $(GIT_URL) ($(
|
67
|
+
@echo "ChangeLog from $(GIT_URL) ($(log_range))" > $@+
|
71
68
|
@echo >> $@+
|
72
69
|
git log $(log_range) | sed -e 's/^/ /' >> $@+
|
73
70
|
mv $@+ $@
|
@@ -80,6 +77,7 @@ atom = <link rel="alternate" title="Atom feed" href="$(1)" \
|
|
80
77
|
# using rdoc 2.4.1+
|
81
78
|
doc: .document NEWS ChangeLog
|
82
79
|
for i in $(man1_bins); do > $$i; done
|
80
|
+
find bin lib -type f -name '*.rbc' -exec rm -f '{}' ';'
|
83
81
|
rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)"
|
84
82
|
install -m644 COPYING doc/COPYING
|
85
83
|
install -m644 $(shell grep '^[A-Z]' .document) doc/
|
@@ -94,8 +92,13 @@ doc: .document NEWS ChangeLog
|
|
94
92
|
$(RUBY) -i -p -e \
|
95
93
|
'$$_.gsub!("</title>",%q{\&$(call atom,$(news_atom))})' \
|
96
94
|
doc/NEWS.html doc/README.html
|
97
|
-
$(
|
95
|
+
$(RAKE) -s news_atom > doc/NEWS.atom.xml
|
98
96
|
cd doc && ln README.html tmp && mv tmp index.html
|
97
|
+
$(MAKE) -C Documentation comparison.html
|
98
|
+
$(RUBY) -i -p -e \
|
99
|
+
'$$_.gsub!(/INCLUDE/){File.read("Documentation/comparison.html")}' \
|
100
|
+
doc/Summary.html
|
101
|
+
cat Documentation/comparison.css >> doc/rdoc.css
|
99
102
|
$(RM) $(man1_bins)
|
100
103
|
|
101
104
|
ifneq ($(VERSION),)
|
@@ -109,10 +112,10 @@ release_changes := release_changes-$(VERSION)
|
|
109
112
|
release-notes: $(release_notes)
|
110
113
|
release-changes: $(release_changes)
|
111
114
|
$(release_changes):
|
112
|
-
$(
|
115
|
+
$(RAKE) -s release_changes > $@+
|
113
116
|
$(VISUAL) $@+ && test -s $@+ && mv $@+ $@
|
114
117
|
$(release_notes):
|
115
|
-
GIT_URL=$(GIT_URL) $(
|
118
|
+
GIT_URL=$(GIT_URL) $(RAKE) -s release_notes > $@+
|
116
119
|
$(VISUAL) $@+ && test -s $@+ && mv $@+ $@
|
117
120
|
|
118
121
|
# ensures we're actually on the tagged $(VERSION), only used for release
|
@@ -150,10 +153,14 @@ $(pkgtgz): manifest fix-perms
|
|
150
153
|
package: $(pkgtgz) $(pkggem)
|
151
154
|
|
152
155
|
release: verify package $(release_notes) $(release_changes)
|
156
|
+
# make tgz release on RubyForge
|
153
157
|
rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
|
154
158
|
$(rfproject) $(rfpackage) $(VERSION) $(pkggem)
|
155
|
-
|
156
|
-
|
159
|
+
# push gem to Gemcutter
|
160
|
+
gem push $(pkggem)
|
161
|
+
# in case of gem downloads from RubyForge releases page
|
162
|
+
-rubyforge add_file \
|
163
|
+
$(rfproject) $(rfpackage) $(VERSION) $(pkggem)
|
157
164
|
else
|
158
165
|
gem install-gem: GIT-VERSION-FILE
|
159
166
|
$(MAKE) $@ VERSION=$(GIT_VERSION)
|
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Rainbows! Unicorn for sleepy apps and slow clients
|
2
2
|
|
3
|
-
Rainbows! is
|
3
|
+
Rainbows! is an HTTP server for sleepy Rack applications. It is based on
|
4
4
|
Unicorn, but designed to handle applications that expect long
|
5
5
|
request/response times and/or slow clients. For Rack applications not
|
6
6
|
heavily bound by slow external network dependencies, consider Unicorn
|
@@ -13,24 +13,23 @@ suck; differently.
|
|
13
13
|
|
14
14
|
For network concurrency, models we currently support are:
|
15
15
|
|
16
|
-
* {
|
17
|
-
* {
|
18
|
-
* {
|
19
|
-
* {
|
20
|
-
* {
|
16
|
+
* {Revactor}[link:Rainbows/Revactor.html]
|
17
|
+
* {ThreadPool}[link:Rainbows/ThreadPool.html]
|
18
|
+
* {Rev}[link:Rainbows/Rev.html]
|
19
|
+
* {ThreadSpawn}[link:Rainbows/ThreadSpawn.html]
|
20
|
+
* {EventMachine}[link:Rainbows/EventMachine.html]
|
21
|
+
* {RevThreadSpawn}[link:Rainbows/RevThreadSpawn.html]
|
22
|
+
* {FiberSpawn}[link:Rainbows/FiberSpawn.html]
|
23
|
+
* {FiberPool}[link:Rainbows/FiberPool.html]
|
24
|
+
* {NeverBlock}[link:Rainbows/NeverBlock.html]
|
21
25
|
|
22
|
-
We have {more on the way}[link:TODO.html] for handling network
|
23
|
-
Additionally, we also use multiple processes (managed by
|
24
|
-
CPU/memory/disk concurrency.
|
26
|
+
We have {many more on the way}[link:TODO.html] for handling network
|
27
|
+
concurrency. Additionally, we also use multiple processes (managed by
|
28
|
+
Unicorn) for robustness and CPU/memory/disk concurrency.
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
For application concurrency, we have the Rainbows::AppPool Rack
|
31
|
-
middleware that allows us to limit application concurrency independently
|
32
|
-
of network concurrency. Rack::Lock as distributed by Rack may also be
|
33
|
-
used to limit application concurrency to one (per-worker).
|
30
|
+
We also provide Rainbows::AppPool Rack middleware for some network
|
31
|
+
concurrency models for limiting application concurrency independently of
|
32
|
+
network concurrency.
|
34
33
|
|
35
34
|
== Features
|
36
35
|
|
@@ -38,8 +37,8 @@ used to limit application concurrency to one (per-worker).
|
|
38
37
|
modern Ruby HTTP applications.
|
39
38
|
|
40
39
|
* Built on {Unicorn}[http://unicorn.bogomips.org/], inheriting its
|
41
|
-
process/socket management features
|
42
|
-
|
40
|
+
process/socket management features such as transparent upgrades and
|
41
|
+
Ruby configuration DSL.
|
43
42
|
|
44
43
|
* As with Unicorn, it is able to stream large request bodies off the
|
45
44
|
socket to the application while the client is still uploading. Since
|
@@ -47,13 +46,16 @@ used to limit application concurrency to one (per-worker).
|
|
47
46
|
it is with Unicorn.
|
48
47
|
|
49
48
|
* Combines heavyweight concurrency (worker processes) with lightweight
|
50
|
-
concurrency (Actors
|
51
|
-
independently of client connections.
|
49
|
+
concurrency (Events/Fibers/Actors/Threads), allowing CPU/memory/disk to
|
50
|
+
be scaled independently of client connections. More concurrency models
|
52
51
|
(listed in the TODO) will be supported as we find time for them.
|
53
52
|
|
53
|
+
* We give you {lots of options}[link:Summary.html] with more
|
54
|
+
{on the way}[link:TODO.html].
|
55
|
+
|
54
56
|
== Applications
|
55
57
|
|
56
|
-
\Rainbows is for the odd things Unicorn sucks at:
|
58
|
+
\Rainbows is mainly designed for the odd things Unicorn sucks at:
|
57
59
|
|
58
60
|
* 3rd-party APIs (to services outside your control/LAN)
|
59
61
|
* OpenID consumers (to providers outside your control/LAN)
|
@@ -63,10 +65,12 @@ used to limit application concurrency to one (per-worker).
|
|
63
65
|
* BOSH (with slow clients)
|
64
66
|
* HTTP server push
|
65
67
|
* Long polling
|
66
|
-
* Reverse
|
68
|
+
* Reverse AJAX
|
69
|
+
* HTML 5 Web Sockets
|
70
|
+
* real-time upload processing
|
67
71
|
|
68
|
-
\Rainbows
|
69
|
-
applications
|
72
|
+
\Rainbows can also be used to service slow clients directly even with
|
73
|
+
fast applications.
|
70
74
|
|
71
75
|
== License
|
72
76
|
|
@@ -86,7 +90,7 @@ and run setup.rb after unpacking it:
|
|
86
90
|
|
87
91
|
http://rubyforge.org/frs/?group_id=8977
|
88
92
|
|
89
|
-
You may also install it via
|
93
|
+
You may also install it via RubyGems on Gemcutter:
|
90
94
|
|
91
95
|
gem install rainbows
|
92
96
|
|
@@ -125,13 +129,13 @@ You can get the latest source via git from the following locations
|
|
125
129
|
(these versions may not be stable):
|
126
130
|
|
127
131
|
git://git.bogomips.org/rainbows.git
|
128
|
-
git://
|
132
|
+
git://repo.or.cz/rainbows.git (mirror)
|
129
133
|
|
130
134
|
You may browse the code from the web and download the latest snapshot
|
131
135
|
tarballs here:
|
132
136
|
|
133
137
|
* http://git.bogomips.org/cgit/rainbows.git (cgit)
|
134
|
-
* http://
|
138
|
+
* http://repo.or.cz/w/rainbows.git (gitweb)
|
135
139
|
|
136
140
|
Inline patches (from "git format-patch") to the mailing list are
|
137
141
|
preferred because they allow code review and comments in the reply to
|