thread_timeout: avoid a threading bug under 1.9
[rainbows.git] / Documentation / comparison.haml
blobd9382bc880b31a4993af3413df75f485be8378d2
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 Yes
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   %tr.comp_row
89     %td.mod RevThreadPool
90     %td.tee No
91     %td.r18 Yes
92     %td.r19 No
93     %td.rbx No
94     %td.slow Yes
95   %tr.comp_row
96     %td.mod RevFiberSpawn
97     %td.tee Yes
98     %td.r18 No
99     %td.r19 Yes
100     %td.rbx No
101     %td.slow Yes
102   %tr.comp_row
103     %td.mod WriterThreadPool
104     %td.tee Yes
105     %td.r18 Yes
106     %td.r19 Yes
107     %td.rbx Yes
108     %td.slow no
109   %tr.comp_row
110     %td.mod WriterThreadSpawn
111     %td.tee Yes
112     %td.r18 Yes
113     %td.r19 Yes
114     %td.rbx Yes
115     %td.slow no
117   %li
118     RevThread* + 1.8 requires Rev >= 0.3.2 for reasonable performance
119   %li
120     waiting on Rubinius for better signal handling
121   %li
122     rack.input streaming is what makes
123     %a(href="http://upr.bogomips.org/") upload progress,
124     and BOSH possible
125   %li
126     rack.input streaming is NOT compatible with current versions of nginx
127     or any proxy that fully buffers request bodies before proxying.
128     Keep in mind request body buffering in nginx is a good thing in all
129     other cases where rack.input streaming is not needed.
131 %h2 application requirements
133 %table.comp
134   %tr.comp_header
135     %th.mod module
136     %th.slowio slow I/O (backend, not client)
137     %th.thr thread safety
138     %th.reent single thread reentrant
139   %tr.comp_base
140     %td.mod Unicorn/Base
141     %td.slowio avoid
142     %td.thr No
143     %td.reent No
144   %tr.comp_row
145     %td.mod Revactor
146     %td.slowio
147       %a(href="http://rev.rubyforge.org/")Rev,
148       %a(href="http://revactor.org/")Revactor,
149       %b
150         not
151       %a(href="Rainbows/Fiber/IO.html")Fiber::IO
152     %td.thr No
153     %td.reent Yes
154   %tr.comp_row
155     %td.mod ThreadPool
156     %td.slowio thread-safe Ruby
157     %td.thr Yes
158     %td.reent No
159   %tr.comp_row
160     %td.mod Rev
161     %td.slowio
162       %a(href="http://rev.rubyforge.org/") Rev
163     %td.thr No
164     %td.reent No
165   %tr.comp_row
166     %td.mod ThreadSpawn
167     %td.slowio thread-safe Ruby
168     %td.thr Yes
169     %td.reent No
170   %tr.comp_row
171     %td.mod EventMachine
172     %td.slowio
173       %a(href="http://rubyeventmachine.com") EventMachine
174     %td.thr No
175     %td.reent No
176   %tr.comp_row
177     %td.mod RevThreadSpawn
178     %td.slowio
179       thread-safe Ruby,
180       %a(href="http://rev.rubyforge.org/") Rev
181     %td.thr Yes
182     %td.reent No
183   %tr.comp_row
184     %td.mod FiberSpawn
185     %td.slowio
186       %a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
187     %td.thr No
188     %td.reent Yes
189   %tr.comp_row
190     %td.mod FiberPool
191     %td.slowio
192       %a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
193     %td.thr No
194     %td.reent Yes
195   %tr.comp_base
196     %td.mod ActorSpawn
197     %td.slowio thread-safe Ruby
198     %td.thr Yes
199     %td.reent Yes
200   %tr.comp_base
201     %td.mod NeverBlock
202     %td.slowio
203       %a(href="http://www.espace.com.eg/neverblock") NeverBlock,
204       %a(href="http://rubyeventmachine.com") EventMachine
205     %td.thr No
206     %td.reent Yes
207   %tr.comp_row
208     %td.mod RevThreadPool
209     %td.slowio
210       thread-safe Ruby,
211       %a(href="http://rev.rubyforge.org/") Rev
212     %td.thr Yes
213     %td.reent No
214   %tr.comp_row
215     %td.mod RevFiberSpawn
216     %td.slowio
217       %a(href="Rainbows/Fiber/IO.html") Rainbows::Fiber::IO
218     %td.thr No
219     %td.reent Yes
220   %tr.comp_base
221     %td.mod WriterThreadPool
222     %td.slowio avoid
223     %td.thr Maybe
224     %td.reent Maybe
225   %tr.comp_base
226     %td.mod WriterThreadSpawn
227     %td.slowio avoid
228     %td.thr Maybe
229     %td.reent Maybe
231   %li
232     Requirements for single thread reentrancy are loose in that there is
233     no risk of race conditions and potentially mutually exclusive to
234     thread-safety.  In the case where a Fiber yields while holding a
235     resource and another Fiber attempting to acquire it may raise
236     an error or worse, deadlock the entire process.
237   %li
238     Slow I/O means anything that can block/stall on sockets including
239     3rd-party APIs (OpenID providers included) or slow database queries.
240     Properly run Memcached (within the same LAN) is fast and not a blocker.
241     Slow I/O on POSIX filesystems only includes a few operations, namely
242     on UNIX domain sockets and named pipes.  Nearly all other operations
243     on POSIX filesystems can be considered "fast", or at least
244     uninterruptible.
245   %li
246     WriterThread{Pool,Spawn} will require thread safety if your response
247     body is dynamically generated during the body#each call.
249 %h2 middlewares and frameworks
252 %table.comp
253   %tr.comp_header
254     %th.mod model
255     %th.devfd
256       %a(href="Rainbows/DevFdResponse.html") DevFdResponse
257     %th.app_pool
258       %a(href="Rainbows/AppPool.html") AppPool
259     %th.lock
260       %a(href="http://rack.rubyforge.org/doc/Rack/Lock.html") Rack::Lock
261     %th.async async
262     %th.ws Web Sockets
263   %tr.comp_row
264     %td.mod Unicorn/Base
265     %td.devfd no-op
266     %td.app_pool no-op
267     %td.lock no-op
268     %td.async lots of RAM :P
269     %td.ws no
270   %tr.comp_row
271     %td.mod Revactor
272     %td.devfd no-op
273     %td.app_pool Yes
274     %td.lock No!
275     %td.async Revactor itself
276     %td.ws Sunshowers
277   %tr.comp_row
278     %td.mod ThreadPool
279     %td.devfd Yes
280     %td.app_pool Yes
281     %td.lock Yes
282     %td.async standard Ruby
283     %td.ws Sunshowers
284   %tr.comp_row
285     %td.mod Rev
286     %td.devfd Yes
287     %td.app_pool no-op
288     %td.lock no-op
289     %td.async DevFdResponse
290     %td.ws no
291   %tr.comp_row
292     %td.mod ThreadSpawn
293     %td.devfd Yes
294     %td.app_pool Yes
295     %td.lock Yes
296     %td.async standard Ruby
297     %td.ws Sunshowers
298   %tr.comp_row
299     %td.mod EventMachine
300     %td.devfd Yes
301     %td.app_pool no-op
302     %td.lock no-op
303     %td.async async_sinatra, Cramp, rack-fiber_pool
304     %td.ws no
305   %tr.comp_row
306     %td.mod RevThreadSpawn
307     %td.devfd Yes
308     %td.app_pool Yes
309     %td.lock Dumb
310     %td.async standard Ruby
311     %td.ws no
312   %tr.comp_row
313     %td.mod FiberSpawn
314     %td.devfd Yes
315     %td.app_pool Yes
316     %td.lock No!
317     %td.async Rainbows::Fiber::IO, Rainbows.sleep
318     %td.ws Sunshowers
319   %tr.comp_row
320     %td.mod FiberPool
321     %td.devfd Yes
322     %td.app_pool Yes
323     %td.lock No!
324     %td.async Rainbows::Fiber::IO, Rainbows.sleep
325     %td.ws Sunshowers
326   %tr.comp_row
327     %td.mod ActorSpawn
328     %td.devfd no-op
329     %td.app_pool Yes
330     %td.lock Yes
331     %td.async standard Ruby
332     %td.ws Sunshowers
333   %tr.comp_row
334     %td.mod NeverBlock
335     %td.devfd Yes
336     %td.app_pool Yes*
337     %td.lock Yes*
338     %td.async NeverBlock, async_sinatra
339     %td.ws no
340   %tr.comp_row
341     %td.mod RevThreadPool
342     %td.devfd Yes
343     %td.app_pool Yes
344     %td.lock Dumb
345     %td.async Rev, standard Ruby
346     %td.ws no
347   %tr.comp_row
348     %td.mod RevFiberSpawn
349     %td.devfd Yes
350     %td.app_pool Yes
351     %td.lock No!
352     %td.async Rev, Rainbows::Fiber::IO, Rainbows.sleep
353   %tr.comp_row
354     %td.mod WriterThreadPool
355     %td.devfd Yes
356     %td.app_pool no-op
357     %td.lock no-op
358     %td.async Standard Ruby in response body only
359     %td.ws response body only
360   %tr.comp_row
361     %td.mod WriterThreadSpawn
362     %td.devfd Yes
363     %td.app_pool no-op
364     %td.lock no-op
365     %td.async Standard Ruby in response body only
366     %td.ws response body only
368   %li
369     "No!" means it's fundamentally incompatible, use an
370     %a(href="Rainbows/AppPool.html") AppPool
371     %b :size
372     of one instead.
373   %li
374     NeverBlock also supports a :pool_size option which is one less
375     layer of complexity than using AppPool.
376   %li
377     NeverBlock can neuter the Mutex class so Rack::Lock effectively
378     becomes a no-op with:
379     %br
380     %code require "never_block/frameworks/rails"
381     (before Rails is loaded)
382   %li
383     Everything that's DevFdResponse-compatible can use it for passing
384     async responses through