rack-jet_router 1.2.0 → 1.3.1

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/bench/bench.rb ADDED
@@ -0,0 +1,367 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ ##
5
+ ## Usage:
6
+ ## $ gem install bundler
7
+ ## $ bundler install
8
+ ## $ ruby bench.rb --N=1000_000
9
+ ## $ ruby bench.rb --N=1000_000 --rack=0 --sinatra=0 --multiplexer=0 # --hanami=0 --jetrouter=0 --keight=0
10
+ ##
11
+
12
+
13
+ $LOAD_PATH << File.absolute_path("../../lib", __FILE__)
14
+
15
+ require 'benchmarker'
16
+ Benchmarker.parse_cmdopts()
17
+
18
+ require 'rack' rescue nil unless '0' == $opt_rack
19
+ require 'rack/jet_router' rescue nil unless '0' == $opt_jetrouter
20
+ require 'rack/multiplexer' rescue nil unless '0' == $opt_multiplexer
21
+ require 'sinatra/base' rescue nil unless '0' == $opt_sinatra
22
+ require 'keight' rescue nil unless '0' == $opt_keight
23
+ require 'hanami/router' rescue nil unless '0' == $opt_hanami
24
+
25
+ flag_rack = defined?(Rack) && $opt_rack != '0'
26
+ flag_jetrouter = defined?(Rack::JetRouter)
27
+ flag_multiplexer = defined?(Rack::Multiplexer)
28
+ flag_sinatra = defined?(Sinatra)
29
+ flag_keight = defined?(K8)
30
+ flag_hanami = defined?(Hanami::Router)
31
+
32
+ def version_info(name, opt, flag)
33
+ version = opt == '0' ? "(skipped)" \
34
+ : ! flag ? "(not installed)" \
35
+ : yield
36
+ return "** %-20s : %s" % [name, version]
37
+ end
38
+
39
+ puts version_info("rack" , $opt_rack , flag_rack ) { Rack.release }
40
+ puts version_info("rack-jet_router" , $opt_jetrouter , flag_jetrouter ) { Rack::JetRouter::RELEASE }
41
+ puts version_info("rack-multiplexer", $opt_multiplexer, flag_multiplexer) { Rack::Multiplexer::VERSION }
42
+ puts version_info("sinatra" , $opt_sinatra , flag_sinatra ) { Sinatra::VERSION }
43
+ puts version_info("keight" , $opt_keight , flag_keight ) { K8::RELEASE }
44
+ puts version_info("hanami-router" , $opt_hanami , flag_hanami ) { Hanami::Router::VERSION }
45
+
46
+
47
+ ENTRIES = ('a'..'z').map.with_index {|x, i| "%s%02d" % [x*3, i+1] }
48
+
49
+ #flag_sinatra = false # because too slow
50
+ target_urlpaths = [
51
+ "/api/aaa01",
52
+ "/api/aaa01/123",
53
+ # "/api/aaa01/123/comments/7",
54
+ "/api/zzz26",
55
+ "/api/zzz26/456",
56
+ # "/api/zzz26/456/comments/7",
57
+ ]
58
+
59
+
60
+ if flag_rack
61
+
62
+ rack_app1 = proc do |env|
63
+ [200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
64
+ end
65
+
66
+ rack_app4 = proc do |env; req, resp|
67
+ req = Rack::Request.new(env)
68
+ resp = Rack::Response.new
69
+ #[resp.status, resp.headers, ["<h1>hello</h1>"]]
70
+ #[200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
71
+ resp.status = 200
72
+ resp.headers["Content-Type"] = "text/html"
73
+ resp.write("<h1>hello</h1>")
74
+ resp.finish()
75
+ end
76
+
77
+ end
78
+
79
+
80
+ if flag_jetrouter
81
+
82
+ jet_router = proc {
83
+ handler1 = proc {|env|
84
+ [200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
85
+ }
86
+ handler2 = proc {|env|
87
+ d = env['rack.urlpath_params']
88
+ [200, {"Content-Type"=>"text/html"}, ["<h1>id=#{d['id']}</h1>"]]
89
+ }
90
+ handler3 = proc {|env|
91
+ d = env['rack.urlpath_params']
92
+ [200, {"Content-Type"=>"text/html"}, ["<h1>id=#{d['id']}, comment_id=#{d['comment_id']}</h1>"]]
93
+ }
94
+ mapping = [
95
+ ['/api', ENTRIES.each_with_object([]) {|x, arr|
96
+ arr << ["/#{x}", [
97
+ ['', handler1],
98
+ ['/:id', handler2],
99
+ ]]
100
+ arr << ["/#{x}/:id/comments", [
101
+ ['/:comment_id', handler3],
102
+ ]]
103
+ },
104
+ ],
105
+ ]
106
+ opts = {
107
+ cache_size: ($opt_k8cache || 0).to_i,
108
+ _enable_range: $opt_k8range != '0',
109
+ #prefix_minlength_target: /\A\/api\/\w/,
110
+ }
111
+ Rack::JetRouter.new(mapping, **opts)
112
+ }.call()
113
+
114
+ end
115
+
116
+
117
+ if flag_multiplexer
118
+
119
+ mpx_app = Rack::Multiplexer.new().tap do |app|
120
+ handler1 = proc {|env|
121
+ [200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
122
+ }
123
+ handler2 = proc {|env|
124
+ d = env['rack.request.query_hash']
125
+ [200, {"Content-Type"=>"text/html"}, ["<h1>id=#{d['id']}</h1>"]]
126
+ }
127
+ handler3 = proc {|env|
128
+ d = env['rack.request.query_hash']
129
+ [200, {"Content-Type"=>"text/html"}, ["<h1>id=#{d['id']}, comment_id=#{d['comment_id']}</h1>"]]
130
+ }
131
+ ENTRIES.each do |x|
132
+ app.get "/api/#{x}" , handler1
133
+ app.get "/api/#{x}/:id" , handler2
134
+ app.get "/api/#{x}/:id/comments/:comment_id" , handler3
135
+ end
136
+ end
137
+
138
+ end
139
+
140
+
141
+ if flag_sinatra
142
+
143
+ class SinaApp < Sinatra::Base
144
+ ## run benchmarks without middlewares
145
+ set :sessions , false
146
+ set :logging , false
147
+ set :protection , false
148
+ set :x_cascade , false
149
+ #
150
+ ENTRIES.each do |x|
151
+ get "/api/#{x}" do "<h1>hello</h1>" end
152
+ get "/api/#{x}/:id" do "<h1>id=#{params['id']}</h1>" end
153
+ get "/api/#{x}/:id/comments/:comment_id" do "<h1>id=#{params['id']}, comment_id=#{params['comment_id']}</h1>" end
154
+ end
155
+ end
156
+
157
+ sina_app = SinaApp.new
158
+
159
+ end
160
+
161
+
162
+ if flag_keight
163
+
164
+ class K8HelloAction < K8::Action
165
+ mapping '', :GET=>:do_index
166
+ mapping '/{id}', :GET=>:do_show
167
+ def do_index ; "<h1>hello</h1>"; end
168
+ def do_show(id) ; "<h1>id=#{id.inspect}</h1>"; end
169
+ end
170
+
171
+ class K8CommentAction < K8::Action
172
+ mapping '/{comment_id}', :GET=>:do_show
173
+ def do_show(id, comment_id); "<h1>id=#{id}, comment_id=#{comment_id}</h1>"; end
174
+ end
175
+
176
+ k8_app = (proc {
177
+ mapping = [
178
+ ["/api", ENTRIES.each_with_object([]) {|x, arr|
179
+ arr << ["/#{x}" , K8HelloAction]
180
+ arr << ["/#{x}/{id}/comments", K8CommentAction]
181
+ }
182
+ ],
183
+ ]
184
+ opts = {
185
+ #urlpath_cache_size: 0,
186
+ }
187
+ K8::RackApplication.new(mapping, **opts)
188
+ }).call()
189
+
190
+ #k8_app.find('/api/books') # warm up
191
+
192
+ end
193
+
194
+
195
+ if flag_hanami
196
+
197
+ ## ref: https://github.com/hanami/router
198
+ hanami_app = Hanami::Router.new do
199
+ index_handler = proc do |env|
200
+ [200, {"Content-Type": "text/html"}, ["<h1>hello</h1>"]]
201
+ end
202
+ show_handler = proc do |env|
203
+ d = env['router.params']
204
+ [200, {"Content-Type": "text/html"}, ["<h1>id=#{d[:id]}</h1>"]]
205
+ end
206
+ comment_handler = proc do |env|
207
+ d = env['router.params']
208
+ [200, {"Content-Type": "text/html"}, ["<h1>id=#{d[:id]}, comment_id=#{d[:comment_id]}</h1>"]]
209
+ end
210
+ #
211
+ scope "api" do
212
+ ENTRIES.each do |x|
213
+ get "/#{x}" , to: index_handler
214
+ get "/#{x}/:id", to: show_handler
215
+ get "/#{x}/:id/comments/:comment_id", to: comment_handler
216
+ end
217
+ end
218
+ end
219
+
220
+ end
221
+
222
+
223
+ begin
224
+ Rack::MockRequest
225
+ rescue
226
+ require 'rack'
227
+ end
228
+ $environ = Rack::MockRequest.env_for("http://localhost/", method: 'GET')
229
+ $environ.freeze
230
+
231
+ def newenv(path)
232
+ env = $environ.dup
233
+ env['PATH_INFO'] = path
234
+ env
235
+ end
236
+
237
+
238
+ N = ($opt_N || 100000).to_i
239
+ title = "Router library benchmark"
240
+ Benchmarker.scope(title, width: 33, loop: 1, iter: 1, extra: 0, sleep: 0) do
241
+
242
+ puts "** N=#{N}"
243
+ puts ""
244
+
245
+ ### empty task
246
+ task nil do
247
+ i = 0; n = N
248
+ while (i += 1) <= n
249
+ #newenv("/api")
250
+ end
251
+ end
252
+
253
+ ### Rack
254
+ if flag_rack
255
+ #target_urlpaths.each do |x|
256
+ # rack_app1.call(newenv(x)) # warm up
257
+ # task "(Rack plain app) #{x}" do # no routing
258
+ # env = newenv(x)
259
+ # i = 0; n = N
260
+ # while (i += 1) <= n
261
+ # tuple = rack_app1.call(env)
262
+ # end
263
+ # tuple
264
+ # end
265
+ #end
266
+ target_urlpaths.each do |x|
267
+ rack_app4.call(newenv(x)) # warm up
268
+ task "(Rack::Req+Res) #{x}" do # no routing
269
+ env = newenv(x)
270
+ i = 0; n = N
271
+ while (i += 1) <= n
272
+ tuple = rack_app4.call(env)
273
+ end
274
+ tuple
275
+ end
276
+ end
277
+ end
278
+
279
+ ### Rack::JetRouter
280
+ if flag_jetrouter
281
+ target_urlpaths.each do |x|
282
+ jet_router.call(newenv(x)) # warm up
283
+ task "(JetRouter) #{x}" do
284
+ env = newenv(x)
285
+ i = 0; n = N
286
+ while (i += 1) <= n
287
+ tuple = jet_router.call(env)
288
+ end
289
+ tuple
290
+ end
291
+ end
292
+ end
293
+
294
+ ### Rack::Multiplexer
295
+ if flag_multiplexer
296
+ target_urlpaths.each do |x|
297
+ mpx_app.call(newenv(x)) # warm up
298
+ task "(Multiplexer) #{x}" do
299
+ env = newenv(x)
300
+ i = 0; n = N
301
+ while (i += 1) <= n
302
+ tuple = mpx_app.call(env)
303
+ end
304
+ tuple
305
+ end
306
+ end
307
+ end
308
+
309
+ ### Sinatra
310
+ if flag_sinatra
311
+ target_urlpaths.each do |x|
312
+ sina_app.call(newenv(x)) # warm up
313
+ task "(Sinatra) #{x}" do
314
+ env = newenv(x)
315
+ i = 0; n = N
316
+ while (i += 1) <= n
317
+ tuple = sina_app.call(env)
318
+ end
319
+ tuple
320
+ end
321
+ end
322
+ end
323
+
324
+ ### Keight
325
+ if flag_keight
326
+ target_urlpaths.each do |x|
327
+ k8_app.call(newenv(x)) # warm up
328
+ task "(Keight) #{x}" do
329
+ env = newenv(x)
330
+ i = 0; n = N
331
+ while (i += 1) <= n
332
+ tuple = k8_app.call(env)
333
+ end
334
+ tuple
335
+ end
336
+ end
337
+ end
338
+
339
+ ### Hanami
340
+ if flag_hanami
341
+ target_urlpaths.each do |x|
342
+ hanami_app.call(newenv(x)) # warm up
343
+ task "(Hanami::Router) #{x}" do
344
+ env = newenv(x)
345
+ i = 0; n = N
346
+ while (i += 1) <= n
347
+ tuple = hanami_app.call(env)
348
+ end
349
+ tuple
350
+ end
351
+ end
352
+ end
353
+
354
+ ## validation
355
+ validate do |val| # or: validate do |val, task_name, tag|
356
+ tuple = val
357
+ assert tuple[0] == 200, "200 expected but got #{tuple[0]}"
358
+ body = tuple[2].each {|x| break x }
359
+ assert body == "<h1>hello</h1>" || \
360
+ body == "<h1>id=123</h1>" || \
361
+ body == "<h1>id=456</h1>" || \
362
+ body == "<h1>id=123, comment_id=7</h1>" || \
363
+ body == "<h1>id=456, comment_id=7</h1>", \
364
+ "#{body.inspect}: unpexpected body"
365
+ end
366
+
367
+ end