Add -N or --no-default-middleware option.
[rainbows.git] / t / async_examples / async_app.ru
blob29f10f0f5951143270458756b141d54f31a63a34
1 #!/usr/bin/env rackup -s thin
3 #  async_app.ru
4 #  raggi/thin
6 #   A second demo app for async rack + thin app processing!
7 #   Now using http status code 100 instead.
9 #  Created by James Tucker on 2008-06-17.
10 #  Copyright 2008 James Tucker <raggi@rubyforge.org>.
12 #--
13 # Benchmark Results:
15 # raggi@mbk:~$ ab -c 100 -n 500 http://127.0.0.1:3000/
16 # This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
17 # Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
18 # Copyright 2006 The Apache Software Foundation, http://www.apache.org/
20 # Benchmarking 127.0.0.1 (be patient)
21 # Completed 100 requests
22 # Completed 200 requests
23 # Completed 300 requests
24 # Completed 400 requests
25 # Finished 500 requests
28 # Server Software:        thin
29 # Server Hostname:        127.0.0.1
30 # Server Port:            3000
32 # Document Path:          /
33 # Document Length:        12 bytes
35 # Concurrency Level:      100
36 # Time taken for tests:   5.263089 seconds
37 # Complete requests:      500
38 # Failed requests:        0
39 # Write errors:           0
40 # Total transferred:      47000 bytes
41 # HTML transferred:       6000 bytes
42 # Requests per second:    95.00 [#/sec] (mean)
43 # Time per request:       1052.618 [ms] (mean)
44 # Time per request:       10.526 [ms] (mean, across all concurrent requests)
45 # Transfer rate:          8.55 [Kbytes/sec] received
47 # Connection Times (ms)
48 #               min  mean[+/-sd] median   max
49 # Connect:        0    3   2.2      3       8
50 # Processing:  1042 1046   3.1   1046    1053
51 # Waiting:     1037 1042   3.6   1041    1050
52 # Total:       1045 1049   3.1   1049    1057
54 # Percentage of the requests served within a certain time (ms)
55 #   50%   1049
56 #   66%   1051
57 #   75%   1053
58 #   80%   1053
59 #   90%   1054
60 #   95%   1054
61 #   98%   1056
62 #   99%   1057
63 #  100%   1057 (longest request)
65 class DeferrableBody
66   include EventMachine::Deferrable
68   def call(body)
69     body.each do |chunk|
70       @body_callback.call(chunk)
71     end
72   end
74   def each &blk
75     @body_callback = blk
76   end
78 end
80 class AsyncApp
82   # This is a template async response. N.B. Can't use string for body on 1.9
83   AsyncResponse = [-1, {}, []].freeze
85   def call(env)
87     body = DeferrableBody.new
89     # Get the headers out there asap, let the client know we're alive...
90     EventMachine::next_tick { env['async.callback'].call [200, {'Content-Type' => 'text/plain'}, body] }
92     # Semi-emulate a long db request, instead of a timer, in reality we'd be
93     # waiting for the response data. Whilst this happens, other connections
94     # can be serviced.
95     # This could be any callback based thing though, a deferrable waiting on
96     # IO data, a db request, an http request, an smtp send, whatever.
97     EventMachine::add_timer(1) {
98       body.call ["Woah, async!\n"]
100       EventMachine::next_tick {
101         # This could actually happen any time, you could spawn off to new
102         # threads, pause as a good looking lady walks by, whatever.
103         # Just shows off how we can defer chunks of data in the body, you can
104         # even call this many times.
105         body.call ["Cheers then!"]
106         body.succeed
107       }
108     }
110     # throw :async # Still works for supporting non-async frameworks...
112     AsyncResponse # May end up in Rack :-)
113   end
117 # The additions to env for async.connection and async.callback absolutely
118 # destroy the speed of the request if Lint is doing it's checks on env.
119 # It is also important to note that an async response will not pass through
120 # any further middleware, as the async response notification has been passed
121 # right up to the webserver, and the callback goes directly there too.
122 # Middleware could possibly catch :async, and also provide a different
123 # async.connection and async.callback.
125 # use Rack::Lint
126 run AsyncApp.new