doc: switch documentation generation to wrongdoc
[rainbows.git] / Documentation / comparison.haml
blobd1f689f336a51e2bd0355f611608a762d2864d5e
1 %h1 Rainbows! at a glance
2 %p
3   Confused by all the options we give you?  So are we!  Here's some tables
4   to help keep your head straight.  Remember, engineering is all about
5   trade-offs.
6 %h2 core features and compatibility
7 %br
8 %table.comp
9   %tr.comp_header
10     %th.mod module
11     %th.tee rack.input streaming
12     %th.r18 Ruby 1.8
13     %th.r19 Ruby 1.9
14     %th.rbx Rubinius
15     %th.slow slow clients
16   %tr.comp_base
17     %td.mod Unicorn/Base
18     %td.tee Yes
19     %td.r18 Yes
20     %td.r19 Yes
21     %td.rbx Yes
22     %td.slow No
23   %tr.comp_row
24     %td.mod Revactor
25     %td.tee Yes
26     %td.r18 No
27     %td.r19 Yes
28     %td.rbx No
29     %td.slow Yes
30   %tr.comp_row
31     %td.mod ThreadPool
32     %td.tee Yes
33     %td.r18 Yes
34     %td.r19 Yes
35     %td.rbx Yes
36     %td.slow OK
37   %tr.comp_row
38     %td.mod Rev
39     %td.tee No
40     %td.r18 Yes
41     %td.r19 Yes
42     %td.rbx No
43     %td.slow Yes
44   %tr.comp_row
45     %td.mod ThreadSpawn
46     %td.tee Yes
47     %td.r18 Yes
48     %td.r19 Yes
49     %td.rbx Yes
50     %td.slow OK
51   %tr.comp_row
52     %td.mod EventMachine
53     %td.tee No
54     %td.r18 Yes
55     %td.r19 Yes
56     %td.rbx No
57     %td.slow Yes
58   %tr.comp_row
59     %td.mod RevThreadSpawn
60     %td.tee No
61     %td.r18 Yes
62     %td.r19 Yes
63     %td.rbx No
64     %td.slow Yes
65   %tr.comp_row
66     %td.mod FiberSpawn
67     %td.tee Yes
68     %td.r18 No
69     %td.r19 Yes
70     %td.rbx No
71     %td.slow Yes
72   %tr.comp_row
73     %td.mod FiberPool
74     %td.tee Yes
75     %td.r18 No
76     %td.r19 Yes
77     %td.rbx No
78     %td.slow Yes
79   %tr.comp_base
80     %td.mod ActorSpawn
81     %td.tee Yes
82     %td.r18 Not yet
83     %td.r19 No
84     %td.rbx Yes
85     %td.slow Yes
86   %tr.comp_base
87     %td.mod NeverBlock
88     %td.tee No
89     %td.r18 Yes
90     %td.r19 Yes
91     %td.rbx No
92     %td.slow Yes
93   %tr.comp_row
94     %td.mod RevThreadPool
95     %td.tee No
96     %td.r18 Yes
97     %td.r19 No
98     %td.rbx No
99     %td.slow Yes
100   %tr.comp_row
101     %td.mod RevFiberSpawn
102     %td.tee Yes
103     %td.r18 No
104     %td.r19 Yes
105     %td.rbx No
106     %td.slow Yes
107   %tr.comp_row
108     %td.mod WriterThreadPool
109     %td.tee Yes
110     %td.r18 Yes
111     %td.r19 Yes
112     %td.rbx Yes
113     %td.slow no
114   %tr.comp_row
115     %td.mod WriterThreadSpawn
116     %td.tee Yes
117     %td.r18 Yes
118     %td.r19 Yes
119     %td.rbx Yes
120     %td.slow no
122   %li
123     RevThread* + 1.8 requires Rev >= 0.3.2 for reasonable performance
124   %li
125     waiting on Rubinius for better signal handling
126   %li
127     rack.input streaming is what makes
128     %a(href="http://upr.bogomips.org/") upload progress,
129     and BOSH possible
130   %li
131     rack.input streaming is NOT compatible with current versions of nginx
132     or any proxy that fully buffers request bodies before proxying.
133     Keep in mind request body buffering in nginx is a good thing in all
134     other cases where rack.input streaming is not needed.
136 %h2 application requirements
138 %table.comp
139   %tr.comp_header
140     %th.mod module
141     %th.slowio slow I/O (backend, not client)
142     %th.thr thread safety
143     %th.reent single thread reentrant
144   %tr.comp_base
145     %td.mod Unicorn/Base
146     %td.slowio avoid
147     %td.thr No
148     %td.reent No
149   %tr.comp_row
150     %td.mod Revactor
151     %td.slowio
152       %a(href="http://rev.rubyforge.org/")Rev,
153       %a(href="http://revactor.org/")Revactor,
154       %b
155         not
156       %a(href="Rainbows/Fiber/IO.html")Fiber::IO
157     %td.thr No
158     %td.reent Yes
159   %tr.comp_row
160     %td.mod ThreadPool
161     %td.slowio thread-safe Ruby
162     %td.thr Yes
163     %td.reent No
164   %tr.comp_row
165     %td.mod Rev
166     %td.slowio
167       %a(href="http://rev.rubyforge.org/") Rev
168     %td.thr No
169     %td.reent No
170   %tr.comp_row
171     %td.mod ThreadSpawn
172     %td.slowio thread-safe Ruby
173     %td.thr Yes
174     %td.reent No
175   %tr.comp_row
176     %td.mod EventMachine
177     %td.slowio
178       %a(href="http://rubyeventmachine.com") EventMachine
179     %td.thr No
180     %td.reent No
181   %tr.comp_row
182     %td.mod RevThreadSpawn
183     %td.slowio
184       thread-safe Ruby,
185       %a(href="http://rev.rubyforge.org/") Rev
186     %td.thr Yes
187     %td.reent No
188   %tr.comp_row
189     %td.mod FiberSpawn
190     %td.slowio
191       %a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
192     %td.thr No
193     %td.reent Yes
194   %tr.comp_row
195     %td.mod FiberPool
196     %td.slowio
197       %a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
198     %td.thr No
199     %td.reent Yes
200   %tr.comp_base
201     %td.mod ActorSpawn
202     %td.slowio thread-safe Ruby
203     %td.thr Yes
204     %td.reent Yes
205   %tr.comp_base
206     %td.mod NeverBlock
207     %td.slowio
208       %a(href="http://www.espace.com.eg/neverblock") NeverBlock,
209       %a(href="http://rubyeventmachine.com") EventMachine
210     %td.thr No
211     %td.reent Yes
212   %tr.comp_row
213     %td.mod RevThreadPool
214     %td.slowio
215       thread-safe Ruby,
216       %a(href="http://rev.rubyforge.org/") Rev
217     %td.thr Yes
218     %td.reent No
219   %tr.comp_row
220     %td.mod RevFiberSpawn
221     %td.slowio
222       %a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
223     %td.thr No
224     %td.reent Yes
225   %tr.comp_base
226     %td.mod WriterThreadPool
227     %td.slowio avoid
228     %td.thr Maybe
229     %td.reent Maybe
230   %tr.comp_base
231     %td.mod WriterThreadSpawn
232     %td.slowio avoid
233     %td.thr Maybe
234     %td.reent Maybe
236   %li
237     Requirements for single thread reentrancy are loose in that there is
238     no risk of race conditions and potentially mutually exclusive to
239     thread-safety.  In the case where a Fiber yields while holding a
240     resource and another Fiber attempting to acquire it may raise
241     an error or worse, deadlock the entire process.
242   %li
243     Slow I/O means anything that can block/stall on sockets including
244     3rd-party APIs (OpenID providers included) or slow database queries.
245     Properly run Memcached (within the same LAN) is fast and not a blocker.
246     Slow I/O on POSIX filesystems only includes a few operations, namely
247     on UNIX domain sockets and named pipes.  Nearly all other operations
248     on POSIX filesystems can be considered "fast", or at least
249     uninterruptible.
250   %li
251     WriterThread{Pool,Spawn} will require thread safety if your response
252     body is dynamically generated during the body#each call.
254 %h2 middlewares and frameworks
257 %table.comp
258   %tr.comp_header
259     %th.mod model
260     %th.devfd
261       %a(href="Rainbows/DevFdResponse.html") DevFdResponse
262     %th.app_pool
263       %a(href="Rainbows/AppPool.html") AppPool
264     %th.lock
265       %a(href="http://rack.rubyforge.org/doc/Rack/Lock.html") Rack::Lock
266     %th.async async
267     %th.ws Web Sockets
268   %tr.comp_row
269     %td.mod Unicorn/Base
270     %td.devfd no-op
271     %td.app_pool no-op
272     %td.lock no-op
273     %td.async lots of RAM :P
274     %td.ws no
275   %tr.comp_row
276     %td.mod Revactor
277     %td.devfd no-op
278     %td.app_pool Yes
279     %td.lock No!
280     %td.async Revactor itself
281     %td.ws Sunshowers
282   %tr.comp_row
283     %td.mod ThreadPool
284     %td.devfd Yes
285     %td.app_pool Yes
286     %td.lock Yes
287     %td.async standard Ruby
288     %td.ws Sunshowers
289   %tr.comp_row
290     %td.mod Rev
291     %td.devfd Yes
292     %td.app_pool no-op
293     %td.lock no-op
294     %td.async DevFdResponse
295     %td.ws no
296   %tr.comp_row
297     %td.mod ThreadSpawn
298     %td.devfd Yes
299     %td.app_pool Yes
300     %td.lock Yes
301     %td.async standard Ruby
302     %td.ws Sunshowers
303   %tr.comp_row
304     %td.mod EventMachine
305     %td.devfd Yes
306     %td.app_pool no-op
307     %td.lock no-op
308     %td.async async_sinatra, Cramp, rack-fiber_pool
309     %td.ws no
310   %tr.comp_row
311     %td.mod RevThreadSpawn
312     %td.devfd Yes
313     %td.app_pool Yes
314     %td.lock Dumb
315     %td.async standard Ruby
316     %td.ws no
317   %tr.comp_row
318     %td.mod FiberSpawn
319     %td.devfd Yes
320     %td.app_pool Yes
321     %td.lock No!
322     %td.async Rainbows::Fiber::IO, Rainbows.sleep
323     %td.ws Sunshowers
324   %tr.comp_row
325     %td.mod FiberPool
326     %td.devfd Yes
327     %td.app_pool Yes
328     %td.lock No!
329     %td.async Rainbows::Fiber::IO, Rainbows.sleep
330     %td.ws Sunshowers
331   %tr.comp_row
332     %td.mod ActorSpawn
333     %td.devfd no-op
334     %td.app_pool Yes
335     %td.lock Yes
336     %td.async standard Ruby
337     %td.ws Sunshowers
338   %tr.comp_row
339     %td.mod NeverBlock
340     %td.devfd Yes
341     %td.app_pool Yes*
342     %td.lock Yes*
343     %td.async NeverBlock, async_sinatra
344     %td.ws no
345   %tr.comp_row
346     %td.mod RevThreadPool
347     %td.devfd Yes
348     %td.app_pool Yes
349     %td.lock Dumb
350     %td.async Rev, standard Ruby
351     %td.ws no
352   %tr.comp_row
353     %td.mod RevFiberSpawn
354     %td.devfd Yes
355     %td.app_pool Yes
356     %td.lock No!
357     %td.async Rev, Rainbows::Fiber::IO, Rainbows.sleep
358   %tr.comp_row
359     %td.mod WriterThreadPool
360     %td.devfd Yes
361     %td.app_pool no-op
362     %td.lock no-op
363     %td.async Standard Ruby in response body only
364     %td.ws response body only
365   %tr.comp_row
366     %td.mod WriterThreadSpawn
367     %td.devfd Yes
368     %td.app_pool no-op
369     %td.lock no-op
370     %td.async Standard Ruby in response body only
371     %td.ws response body only
373   %li
374     "No!" means it's fundamentally incompatible, use an
375     %a(href="Rainbows/AppPool.html") AppPool
376     %b :size
377     of one instead.
378   %li
379     NeverBlock also supports a :pool_size option which is one less
380     layer of complexity than using AppPool.
381   %li
382     NeverBlock can neuter the Mutex class so Rack::Lock effectively
383     becomes a no-op with:
384     %br
385     %code require "never_block/frameworks/rails"
386     (before Rails is loaded)
387   %li
388     Everything that's DevFdResponse-compatible can use it for passing
389     async responses through