rainbows 0.6.0 → 0.7.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/.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
|