thin 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.md +83 -0
- data/Rakefile +9 -32
- data/example/vlad.rake +1 -1
- data/lib/rack/adapter/loader.rb +0 -16
- data/lib/thin.rb +22 -24
- data/lib/thin/backends/base.rb +3 -1
- data/lib/thin/connection.rb +9 -8
- data/lib/thin/daemonizing.rb +3 -1
- data/lib/thin/logging.rb +1 -1
- data/lib/thin/runner.rb +36 -36
- data/lib/thin/server.rb +13 -0
- data/lib/thin/version.rb +3 -3
- metadata +5 -91
- data/README +0 -69
- data/benchmark/abc +0 -51
- data/benchmark/benchmarker.rb +0 -80
- data/benchmark/runner +0 -82
- data/spec/backends/swiftiply_client_spec.rb +0 -66
- data/spec/backends/tcp_server_spec.rb +0 -33
- data/spec/backends/unix_server_spec.rb +0 -37
- data/spec/command_spec.rb +0 -25
- data/spec/configs/cluster.yml +0 -9
- data/spec/configs/single.yml +0 -9
- data/spec/connection_spec.rb +0 -107
- data/spec/controllers/cluster_spec.rb +0 -267
- data/spec/controllers/controller_spec.rb +0 -129
- data/spec/controllers/service_spec.rb +0 -50
- data/spec/daemonizing_spec.rb +0 -200
- data/spec/headers_spec.rb +0 -40
- data/spec/logging_spec.rb +0 -52
- data/spec/perf/request_perf_spec.rb +0 -50
- data/spec/perf/response_perf_spec.rb +0 -19
- data/spec/perf/server_perf_spec.rb +0 -39
- data/spec/rack/loader_spec.rb +0 -42
- data/spec/rack/rails_adapter_spec.rb +0 -173
- data/spec/rails_app/app/controllers/application.rb +0 -10
- data/spec/rails_app/app/controllers/simple_controller.rb +0 -19
- data/spec/rails_app/app/helpers/application_helper.rb +0 -3
- data/spec/rails_app/app/views/simple/index.html.erb +0 -15
- data/spec/rails_app/config/boot.rb +0 -109
- data/spec/rails_app/config/environment.rb +0 -64
- data/spec/rails_app/config/environments/development.rb +0 -18
- data/spec/rails_app/config/environments/production.rb +0 -19
- data/spec/rails_app/config/environments/test.rb +0 -22
- data/spec/rails_app/config/initializers/inflections.rb +0 -10
- data/spec/rails_app/config/initializers/mime_types.rb +0 -5
- data/spec/rails_app/config/routes.rb +0 -35
- data/spec/rails_app/public/404.html +0 -30
- data/spec/rails_app/public/422.html +0 -30
- data/spec/rails_app/public/500.html +0 -30
- data/spec/rails_app/public/dispatch.cgi +0 -10
- data/spec/rails_app/public/dispatch.fcgi +0 -24
- data/spec/rails_app/public/dispatch.rb +0 -10
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/images/rails.png +0 -0
- data/spec/rails_app/public/index.html +0 -277
- data/spec/rails_app/public/javascripts/application.js +0 -2
- data/spec/rails_app/public/javascripts/controls.js +0 -963
- data/spec/rails_app/public/javascripts/dragdrop.js +0 -972
- data/spec/rails_app/public/javascripts/effects.js +0 -1120
- data/spec/rails_app/public/javascripts/prototype.js +0 -4225
- data/spec/rails_app/public/robots.txt +0 -5
- data/spec/rails_app/script/about +0 -3
- data/spec/rails_app/script/console +0 -3
- data/spec/rails_app/script/destroy +0 -3
- data/spec/rails_app/script/generate +0 -3
- data/spec/rails_app/script/performance/benchmarker +0 -3
- data/spec/rails_app/script/performance/profiler +0 -3
- data/spec/rails_app/script/performance/request +0 -3
- data/spec/rails_app/script/plugin +0 -3
- data/spec/rails_app/script/process/inspector +0 -3
- data/spec/rails_app/script/process/reaper +0 -3
- data/spec/rails_app/script/process/spawner +0 -3
- data/spec/rails_app/script/runner +0 -3
- data/spec/rails_app/script/server +0 -3
- data/spec/request/mongrel_spec.rb +0 -39
- data/spec/request/parser_spec.rb +0 -254
- data/spec/request/persistent_spec.rb +0 -35
- data/spec/request/processing_spec.rb +0 -50
- data/spec/response_spec.rb +0 -102
- data/spec/runner_spec.rb +0 -168
- data/spec/server/builder_spec.rb +0 -44
- data/spec/server/pipelining_spec.rb +0 -110
- data/spec/server/robustness_spec.rb +0 -34
- data/spec/server/stopping_spec.rb +0 -55
- data/spec/server/swiftiply.yml +0 -6
- data/spec/server/swiftiply_spec.rb +0 -32
- data/spec/server/tcp_spec.rb +0 -47
- data/spec/server/threaded_spec.rb +0 -27
- data/spec/server/unix_socket_spec.rb +0 -26
- data/spec/server_spec.rb +0 -100
- data/spec/spec_helper.rb +0 -234
- data/tasks/announce.rake +0 -22
- data/tasks/deploy.rake +0 -13
- data/tasks/email.erb +0 -27
- data/tasks/gem.rake +0 -65
- data/tasks/rdoc.rake +0 -25
- data/tasks/site.rake +0 -15
- data/tasks/spec.rake +0 -43
- data/tasks/stats.rake +0 -28
data/lib/thin/server.rb
CHANGED
@@ -187,6 +187,12 @@ module Thin
|
|
187
187
|
@backend.stop!
|
188
188
|
end
|
189
189
|
|
190
|
+
def reopen_log
|
191
|
+
file = File.expand_path(log_file)
|
192
|
+
log ">> Reopening log file: #{file}"
|
193
|
+
Daemonize.redirect_io(file)
|
194
|
+
end
|
195
|
+
|
190
196
|
# == Configure the server
|
191
197
|
# The process might need to have superuser privilege to configure
|
192
198
|
# server with optimal options.
|
@@ -208,17 +214,24 @@ module Thin
|
|
208
214
|
@backend.running?
|
209
215
|
end
|
210
216
|
|
217
|
+
# deamonizing kills our HUP signal, so we set them again
|
218
|
+
def after_daemonize
|
219
|
+
setup_signals
|
220
|
+
end
|
221
|
+
|
211
222
|
protected
|
212
223
|
# Register signals:
|
213
224
|
# * TERM & QUIT calls +stop+ to shutdown gracefully.
|
214
225
|
# * INT calls <tt>stop!</tt> to force shutdown.
|
215
226
|
# * HUP calls <tt>restart</tt> to ... surprise, restart!
|
227
|
+
# * USR1 reopen log files.
|
216
228
|
def setup_signals
|
217
229
|
trap('INT') { stop! }
|
218
230
|
trap('TERM') { stop }
|
219
231
|
unless Thin.win?
|
220
232
|
trap('QUIT') { stop }
|
221
233
|
trap('HUP') { restart }
|
234
|
+
trap('USR1') { reopen_log }
|
222
235
|
end
|
223
236
|
end
|
224
237
|
|
data/lib/thin/version.rb
CHANGED
@@ -5,12 +5,12 @@ module Thin
|
|
5
5
|
|
6
6
|
module VERSION #:nodoc:
|
7
7
|
MAJOR = 1
|
8
|
-
MINOR =
|
9
|
-
TINY =
|
8
|
+
MINOR = 4
|
9
|
+
TINY = 0
|
10
10
|
|
11
11
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
12
12
|
|
13
|
-
CODENAME = "
|
13
|
+
CODENAME = "Chromeo".freeze
|
14
14
|
|
15
15
|
RACK = [1, 0].freeze # Rack protocol version
|
16
16
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: thin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Marc-Andre Cournoyer
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2012-07-03 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -56,11 +56,8 @@ extra_rdoc_files: []
|
|
56
56
|
|
57
57
|
files:
|
58
58
|
- CHANGELOG
|
59
|
-
- README
|
59
|
+
- README.md
|
60
60
|
- Rakefile
|
61
|
-
- benchmark/abc
|
62
|
-
- benchmark/benchmarker.rb
|
63
|
-
- benchmark/runner
|
64
61
|
- bin/thin
|
65
62
|
- example/adapter.rb
|
66
63
|
- example/async_app.ru
|
@@ -99,89 +96,6 @@ files:
|
|
99
96
|
- lib/thin/statuses.rb
|
100
97
|
- lib/thin/version.rb
|
101
98
|
- lib/thin.rb
|
102
|
-
- spec/backends/swiftiply_client_spec.rb
|
103
|
-
- spec/backends/tcp_server_spec.rb
|
104
|
-
- spec/backends/unix_server_spec.rb
|
105
|
-
- spec/command_spec.rb
|
106
|
-
- spec/configs/cluster.yml
|
107
|
-
- spec/configs/single.yml
|
108
|
-
- spec/connection_spec.rb
|
109
|
-
- spec/controllers/cluster_spec.rb
|
110
|
-
- spec/controllers/controller_spec.rb
|
111
|
-
- spec/controllers/service_spec.rb
|
112
|
-
- spec/daemonizing_spec.rb
|
113
|
-
- spec/headers_spec.rb
|
114
|
-
- spec/logging_spec.rb
|
115
|
-
- spec/perf/request_perf_spec.rb
|
116
|
-
- spec/perf/response_perf_spec.rb
|
117
|
-
- spec/perf/server_perf_spec.rb
|
118
|
-
- spec/rack/loader_spec.rb
|
119
|
-
- spec/rack/rails_adapter_spec.rb
|
120
|
-
- spec/rails_app/app/controllers/application.rb
|
121
|
-
- spec/rails_app/app/controllers/simple_controller.rb
|
122
|
-
- spec/rails_app/app/helpers/application_helper.rb
|
123
|
-
- spec/rails_app/app/views/simple/index.html.erb
|
124
|
-
- spec/rails_app/config/boot.rb
|
125
|
-
- spec/rails_app/config/environment.rb
|
126
|
-
- spec/rails_app/config/environments/development.rb
|
127
|
-
- spec/rails_app/config/environments/production.rb
|
128
|
-
- spec/rails_app/config/environments/test.rb
|
129
|
-
- spec/rails_app/config/initializers/inflections.rb
|
130
|
-
- spec/rails_app/config/initializers/mime_types.rb
|
131
|
-
- spec/rails_app/config/routes.rb
|
132
|
-
- spec/rails_app/public/404.html
|
133
|
-
- spec/rails_app/public/422.html
|
134
|
-
- spec/rails_app/public/500.html
|
135
|
-
- spec/rails_app/public/dispatch.cgi
|
136
|
-
- spec/rails_app/public/dispatch.fcgi
|
137
|
-
- spec/rails_app/public/dispatch.rb
|
138
|
-
- spec/rails_app/public/favicon.ico
|
139
|
-
- spec/rails_app/public/images/rails.png
|
140
|
-
- spec/rails_app/public/index.html
|
141
|
-
- spec/rails_app/public/javascripts/application.js
|
142
|
-
- spec/rails_app/public/javascripts/controls.js
|
143
|
-
- spec/rails_app/public/javascripts/dragdrop.js
|
144
|
-
- spec/rails_app/public/javascripts/effects.js
|
145
|
-
- spec/rails_app/public/javascripts/prototype.js
|
146
|
-
- spec/rails_app/public/robots.txt
|
147
|
-
- spec/rails_app/script/about
|
148
|
-
- spec/rails_app/script/console
|
149
|
-
- spec/rails_app/script/destroy
|
150
|
-
- spec/rails_app/script/generate
|
151
|
-
- spec/rails_app/script/performance/benchmarker
|
152
|
-
- spec/rails_app/script/performance/profiler
|
153
|
-
- spec/rails_app/script/performance/request
|
154
|
-
- spec/rails_app/script/plugin
|
155
|
-
- spec/rails_app/script/process/inspector
|
156
|
-
- spec/rails_app/script/process/reaper
|
157
|
-
- spec/rails_app/script/process/spawner
|
158
|
-
- spec/rails_app/script/runner
|
159
|
-
- spec/rails_app/script/server
|
160
|
-
- spec/request/mongrel_spec.rb
|
161
|
-
- spec/request/parser_spec.rb
|
162
|
-
- spec/request/persistent_spec.rb
|
163
|
-
- spec/request/processing_spec.rb
|
164
|
-
- spec/response_spec.rb
|
165
|
-
- spec/runner_spec.rb
|
166
|
-
- spec/server/builder_spec.rb
|
167
|
-
- spec/server/pipelining_spec.rb
|
168
|
-
- spec/server/robustness_spec.rb
|
169
|
-
- spec/server/stopping_spec.rb
|
170
|
-
- spec/server/swiftiply.yml
|
171
|
-
- spec/server/swiftiply_spec.rb
|
172
|
-
- spec/server/tcp_spec.rb
|
173
|
-
- spec/server/threaded_spec.rb
|
174
|
-
- spec/server/unix_socket_spec.rb
|
175
|
-
- spec/server_spec.rb
|
176
|
-
- spec/spec_helper.rb
|
177
|
-
- tasks/announce.rake
|
178
|
-
- tasks/deploy.rake
|
179
|
-
- tasks/email.erb
|
180
|
-
- tasks/gem.rake
|
181
|
-
- tasks/rdoc.rake
|
182
|
-
- tasks/site.rake
|
183
|
-
- tasks/spec.rake
|
184
|
-
- tasks/stats.rake
|
185
99
|
- ext/thin_parser/ext_help.h
|
186
100
|
- ext/thin_parser/parser.h
|
187
101
|
- ext/thin_parser/parser.c
|
@@ -191,8 +105,8 @@ files:
|
|
191
105
|
- ext/thin_parser/parser.rl
|
192
106
|
has_rdoc: true
|
193
107
|
homepage: http://code.macournoyer.com/thin/
|
194
|
-
licenses:
|
195
|
-
|
108
|
+
licenses:
|
109
|
+
- Ruby
|
196
110
|
post_install_message:
|
197
111
|
rdoc_options: []
|
198
112
|
|
data/README
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
== Thin
|
2
|
-
Tiny, fast & funny HTTP server
|
3
|
-
|
4
|
-
Thin is a Ruby web server that glues together 3 of the best Ruby libraries in web history:
|
5
|
-
* the Mongrel parser: the root of Mongrel speed and security
|
6
|
-
* Event Machine: a network I/O library with extremely high scalability, performance and stability
|
7
|
-
* Rack: a minimal interface between webservers and Ruby frameworks
|
8
|
-
|
9
|
-
Which makes it, with all humility, the most secure, stable, fast and extensible Ruby web server
|
10
|
-
bundled in an easy to use gem for your own pleasure.
|
11
|
-
|
12
|
-
Site: http://code.macournoyer.com/thin/
|
13
|
-
Group: http://groups.google.com/group/thin-ruby/topics
|
14
|
-
Bugs: http://thin.lighthouseapp.com/projects/7212-thin
|
15
|
-
Code: http://github.com/macournoyer/thin
|
16
|
-
IRC: #thin on freenode
|
17
|
-
|
18
|
-
=== Installation
|
19
|
-
For the latest stable version:
|
20
|
-
|
21
|
-
sudo gem install thin
|
22
|
-
|
23
|
-
Or from source:
|
24
|
-
|
25
|
-
git clone git://github.com/macournoyer/thin.git
|
26
|
-
cd thin
|
27
|
-
rake install
|
28
|
-
|
29
|
-
=== Usage
|
30
|
-
A +thin+ script offers an easy way to start your Rails application:
|
31
|
-
|
32
|
-
cd to/your/rails/app
|
33
|
-
thin start
|
34
|
-
|
35
|
-
But Thin is also usable with a Rack config file.
|
36
|
-
You need to setup a config.ru file and pass it to the thin script:
|
37
|
-
|
38
|
-
cat config.ru
|
39
|
-
app = proc do |env|
|
40
|
-
[
|
41
|
-
200,
|
42
|
-
{
|
43
|
-
'Content-Type' => 'text/html',
|
44
|
-
'Content-Length' => '2'
|
45
|
-
},
|
46
|
-
['hi']
|
47
|
-
]
|
48
|
-
end
|
49
|
-
|
50
|
-
run app
|
51
|
-
|
52
|
-
thin start -R config.ru
|
53
|
-
|
54
|
-
See example directory for more samples and run 'thin -h' for usage.
|
55
|
-
|
56
|
-
=== License
|
57
|
-
Ruby License, http://www.ruby-lang.org/en/LICENSE.txt.
|
58
|
-
|
59
|
-
=== Credits
|
60
|
-
The parser was stolen from Mongrel http://mongrel.rubyforge.org by Zed Shaw.
|
61
|
-
Mongrel Web Server (Mongrel) is copyrighted free software by Zed A. Shaw
|
62
|
-
<zedshaw at zedshaw dot com> You can redistribute it and/or modify it under
|
63
|
-
either the terms of the GPL.
|
64
|
-
|
65
|
-
Thin is copyright Marc-Andre Cournoyer <macournoyer@gmail.com>
|
66
|
-
|
67
|
-
Get help at http://groups.google.com/group/thin-ruby/
|
68
|
-
Report bugs at http://thin.lighthouseapp.com/projects/7212-thin
|
69
|
-
and major security issues directly to a team member (see COMMITTERS)
|
data/benchmark/abc
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# Automate benchmarking with ab with various concurrency levels.
|
3
|
-
require 'optparse'
|
4
|
-
|
5
|
-
options = {
|
6
|
-
:address => '0.0.0.0',
|
7
|
-
:port => 3000,
|
8
|
-
:requests => 1000,
|
9
|
-
:start => 1,
|
10
|
-
:end => 100,
|
11
|
-
:step => 10
|
12
|
-
}
|
13
|
-
|
14
|
-
OptionParser.new do |opts|
|
15
|
-
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
16
|
-
|
17
|
-
opts.on("-n", "--requests NUM", "Number of requests") { |num| options[:requests] = num }
|
18
|
-
opts.on("-a", "--address HOST", "Address (default: 0.0.0.0)") { |host| options[:address] = host }
|
19
|
-
opts.on("-p", "--port PORT", "use PORT (default: 3000)") { |port| options[:port] = port.to_i }
|
20
|
-
opts.on("-s", "--start N", "First concurrency level") { |n| options[:start] = n.to_i }
|
21
|
-
opts.on("-e", "--end N", "Last concurrency level") { |n| options[:end] = n.to_i }
|
22
|
-
opts.on("-S", "--step N", "Concurrency level step") { |n| options[:step] = n.to_i }
|
23
|
-
opts.on("-u", "--uri PATH", "Path to send to") { |u| options[:uri] = u }
|
24
|
-
opts.on("-k", "--keep-alive", "Use Keep-Alive") { options[:keep_alive] = true }
|
25
|
-
|
26
|
-
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
27
|
-
end.parse!(ARGV)
|
28
|
-
|
29
|
-
puts 'request concurrency req/s failures'
|
30
|
-
puts '=' * 42
|
31
|
-
|
32
|
-
c = options[:start]
|
33
|
-
until c >= options[:end]
|
34
|
-
sleep 0.5
|
35
|
-
out = `nice -n20 ab #{'-k' if options[:keep_alive]} -c #{c} -n #{options[:requests]} #{options[:address]}:#{options[:port]}/#{options[:uri]} 2> /dev/null`
|
36
|
-
|
37
|
-
r = if requests = out.match(/^Requests.+?(\d+\.\d+)/)
|
38
|
-
requests[1].to_i
|
39
|
-
else
|
40
|
-
0
|
41
|
-
end
|
42
|
-
f = if requests = out.match(/^Failed requests.+?(\d+)/)
|
43
|
-
requests[1].to_i
|
44
|
-
else
|
45
|
-
0
|
46
|
-
end
|
47
|
-
|
48
|
-
puts "#{options[:requests].to_s.ljust(9)} #{c.to_s.ljust(13)} #{r.to_s.ljust(8)} #{f}"
|
49
|
-
|
50
|
-
c += options[:step]
|
51
|
-
end
|
data/benchmark/benchmarker.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'rack/lobster'
|
2
|
-
|
3
|
-
class Benchmarker
|
4
|
-
PORT = 7000
|
5
|
-
ADDRESS = '0.0.0.0'
|
6
|
-
|
7
|
-
attr_accessor :requests, :concurrencies, :servers, :keep_alive
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@servers = %w(Mongrel EMongrel Thin)
|
11
|
-
@requests = 1000
|
12
|
-
@concurrencies = [1, 10, 100]
|
13
|
-
end
|
14
|
-
|
15
|
-
def writer(&block)
|
16
|
-
@writer = block
|
17
|
-
end
|
18
|
-
|
19
|
-
def run!
|
20
|
-
@concurrencies.each do |concurrency|
|
21
|
-
@servers.each do |server|
|
22
|
-
req_sec, failed = run_one(server, concurrency)
|
23
|
-
@writer.call(server, @requests, concurrency, req_sec, failed)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
def start_server(handler_name)
|
30
|
-
@server = fork do
|
31
|
-
[STDOUT, STDERR].each { |o| o.reopen "/dev/null" }
|
32
|
-
|
33
|
-
case handler_name
|
34
|
-
when 'EMongrel'
|
35
|
-
require 'swiftcore/evented_mongrel'
|
36
|
-
handler_name = 'Mongrel'
|
37
|
-
end
|
38
|
-
|
39
|
-
app = proc do |env|
|
40
|
-
[200, {'Content-Type' => 'text/html', 'Content-Length' => '11'}, ['hello world']]
|
41
|
-
end
|
42
|
-
|
43
|
-
handler = Rack::Handler.const_get(handler_name)
|
44
|
-
handler.run app, :Host => ADDRESS, :Port => PORT
|
45
|
-
end
|
46
|
-
|
47
|
-
sleep 2
|
48
|
-
end
|
49
|
-
|
50
|
-
def stop_server
|
51
|
-
Process.kill('SIGKILL', @server)
|
52
|
-
Process.wait
|
53
|
-
end
|
54
|
-
|
55
|
-
def run_ab(concurrency)
|
56
|
-
`nice -n20 ab -c #{concurrency} -n #{@requests} #{@keep_alive ? '-k' : ''} #{ADDRESS}:#{PORT}/ 2> /dev/null`
|
57
|
-
end
|
58
|
-
|
59
|
-
def run_one(handler_name, concurrency)
|
60
|
-
start_server(handler_name)
|
61
|
-
|
62
|
-
out = run_ab(concurrency)
|
63
|
-
|
64
|
-
stop_server
|
65
|
-
|
66
|
-
req_sec = if matches = out.match(/^Requests.+?(\d+\.\d+)/)
|
67
|
-
matches[1].to_i
|
68
|
-
else
|
69
|
-
0
|
70
|
-
end
|
71
|
-
|
72
|
-
failed = if matches = out.match(/^Failed requests.+?(\d+)/)
|
73
|
-
matches[1].to_i
|
74
|
-
else
|
75
|
-
0
|
76
|
-
end
|
77
|
-
|
78
|
-
[req_sec, failed]
|
79
|
-
end
|
80
|
-
end
|
data/benchmark/runner
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# Simple benchmark to compare Thin performance against
|
3
|
-
# other webservers supported by Rack.
|
4
|
-
#
|
5
|
-
# Run with:
|
6
|
-
#
|
7
|
-
# ruby simple.rb [num of request] [print|graph] [concurrency levels]
|
8
|
-
#
|
9
|
-
|
10
|
-
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
11
|
-
require 'thin'
|
12
|
-
|
13
|
-
require File.dirname(__FILE__) + '/benchmarker'
|
14
|
-
require 'optparse'
|
15
|
-
|
16
|
-
options = {
|
17
|
-
:requests => 1000,
|
18
|
-
:concurrencies => [1, 10, 100],
|
19
|
-
:keep_alive => false,
|
20
|
-
:output => :table
|
21
|
-
}
|
22
|
-
|
23
|
-
OptionParser.new do |opts|
|
24
|
-
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
25
|
-
|
26
|
-
opts.on("-n", "--requests NUM", "Number of requests") { |num| options[:requests] = num.to_i }
|
27
|
-
opts.on("-c", "--concurrencies EXP", "Concurrency levels") { |exp| options[:concurrencies] = eval(exp).to_a }
|
28
|
-
opts.on("-k", "--keep-alive", "Use persistent connections") { options[:keep_alive] = true }
|
29
|
-
opts.on("-t", "--table", "Output as text table") { options[:output] = :table }
|
30
|
-
opts.on("-g", "--graph", "Output as graph") { options[:output] = :graph }
|
31
|
-
|
32
|
-
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
33
|
-
end.parse!(ARGV)
|
34
|
-
|
35
|
-
# benchmark output_type, %w(WEBrick Mongrel EMongrel Thin), request, levels
|
36
|
-
b = Benchmarker.new
|
37
|
-
b.requests = options[:requests]
|
38
|
-
b.concurrencies = options[:concurrencies]
|
39
|
-
b.keep_alive = options[:keep_alive]
|
40
|
-
|
41
|
-
case options[:output]
|
42
|
-
when :table
|
43
|
-
puts 'server request concurrency req/s failures'
|
44
|
-
puts '=' * 52
|
45
|
-
|
46
|
-
b.writer do |server, requests, concurrency, req_sec, failed|
|
47
|
-
puts "#{server.ljust(8)} #{requests} #{concurrency.to_s.ljust(4)} #{req_sec.to_s.ljust(8)} #{failed}"
|
48
|
-
end
|
49
|
-
|
50
|
-
b.run!
|
51
|
-
|
52
|
-
when :graph
|
53
|
-
require '/usr/local/lib/ruby/gems/1.8/gems/gruff-0.2.9/lib/gruff'
|
54
|
-
g = Gruff::Area.new
|
55
|
-
g.title = "#{options[:requests]} requests"
|
56
|
-
g.title << ' w/ Keep-Alive' if options[:keep_alive]
|
57
|
-
|
58
|
-
g.x_axis_label = 'Concurrency'
|
59
|
-
g.y_axis_label = 'Requests / sec'
|
60
|
-
g.maximum_value = 0
|
61
|
-
g.minimum_value = 0
|
62
|
-
g.labels = {}
|
63
|
-
b.concurrencies.each_with_index { |c, i| g.labels[i] = c.to_s }
|
64
|
-
|
65
|
-
results = {}
|
66
|
-
|
67
|
-
b.writer do |server, requests, concurrency, req_sec, failed|
|
68
|
-
print '.'
|
69
|
-
results[server] ||= []
|
70
|
-
results[server] << req_sec
|
71
|
-
end
|
72
|
-
|
73
|
-
b.run!
|
74
|
-
puts
|
75
|
-
|
76
|
-
results.each do |server, concurrencies|
|
77
|
-
g.data(server, concurrencies)
|
78
|
-
end
|
79
|
-
|
80
|
-
g.write('bench.png')
|
81
|
-
`open bench.png`
|
82
|
-
end
|