keight 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.txt +64 -0
- data/MIT-LICENSE +1 -1
- data/README.md +180 -55
- data/Rakefile +1 -1
- data/bench/bench.rb +219 -119
- data/bench/benchmarker.rb +5 -3
- data/bin/k8rb +237 -20
- data/keight.gemspec +3 -3
- data/lib/keight.rb +373 -634
- data/lib/keight/skeleton/README.txt +13 -0
- data/lib/keight/skeleton/config.ru +3 -18
- data/lib/keight/skeleton/index.txt +7 -6
- data/lib/keight/skeleton/main.rb +22 -0
- data/lib/keight/skeleton/static/lib/.keep +0 -0
- data/lib/keight/skeleton/test/api/hello_test.rb +27 -0
- data/lib/keight/skeleton/test/test_helper.rb +9 -0
- data/test/keight_test.rb +783 -938
- data/test/oktest.rb +3 -3
- metadata +29 -7
- data/lib/keight/skeleton/static/lib/jquery/1.11.3/jquery.min.js +0 -6
- data/lib/keight/skeleton/static/lib/jquery/1.11.3/jquery.min.js.gz +0 -0
- data/lib/keight/skeleton/static/lib/modernizr/2.8.3/modernizr.min.js +0 -4
- data/lib/keight/skeleton/static/lib/modernizr/2.8.3/modernizr.min.js.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5674423ea6090c2163b9bff12f3ec5f2a1542dce
|
4
|
+
data.tar.gz: ecde3e22c5720bfd8be224b45bb3f2e28db092dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a976045af16e6ff169a3fe46decb0b9c0fe8d30ed4848dc8d5669298766c3651be375c2dc4690614f3b740c4b599ec209594d82203aaf3e3f05397f1eade1a3
|
7
|
+
data.tar.gz: 75720c41ec1250de00b5aeb2c1ed332b674d6c90e7a238bf4263fc1226caf9eedabb9c7d00ca1278f4a9d0609e9f59110d01e0b8e60f7e525d045e01bf744467
|
data/CHANGES.txt
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
Changes
|
2
|
+
=======
|
3
|
+
|
4
|
+
|
5
|
+
Release 0.2.0 (2016-01-06)
|
6
|
+
--------------------------
|
7
|
+
|
8
|
+
* [change] `K8::RackApplication#mount()` is removed.
|
9
|
+
Use `K8::RackApplication.new([...])` instead.
|
10
|
+
|
11
|
+
* [change] `k8rb init` is renamed to `k8rb project`.
|
12
|
+
|
13
|
+
$ k8rb project myapp1
|
14
|
+
$ cd myapp1
|
15
|
+
|
16
|
+
* [enhance] Auto redirection support.
|
17
|
+
For example, `GET /books` is defined and `GET /books/` is requested,
|
18
|
+
then it will be redirected to `GET /books`.
|
19
|
+
|
20
|
+
* [enhance] Performance improved for variable urlpath.
|
21
|
+
|
22
|
+
* [enhance] Implement urlpath helpers.
|
23
|
+
|
24
|
+
p BookAPI[:do_update].method #=> :PUT
|
25
|
+
p BookAPI[:do_update].urlpath(123) #=> '/api/books/123'
|
26
|
+
p BookAPI[:do_update].form_action_attr(123) #=> '/api/books/123?_method=PUT'
|
27
|
+
|
28
|
+
* [change] `k8rb mapping` now prints output in text format, not YAML format.
|
29
|
+
|
30
|
+
* [enhance] `k8rb mapping` supports `--format=FORMAT` option.
|
31
|
+
|
32
|
+
$ k8rb mapping --format=text # or yaml/json/javascript/jquery/angular
|
33
|
+
|
34
|
+
* [enhance] `k8rb` command supports `cdnjs` action which download JavaScript
|
35
|
+
libraries from cdnjs.com.
|
36
|
+
|
37
|
+
$ k8rb cdnjs # list library
|
38
|
+
$ k8rb cdnjs 'jquery*' # search library
|
39
|
+
$ k8rb cdnjs jquery # list versions
|
40
|
+
$ k8rb cdnjs jquery 2.1.4 # download library
|
41
|
+
|
42
|
+
* [change] `k8rb init` command downloads jquery and modernizr from cdnjs.com.
|
43
|
+
|
44
|
+
* [change] `K8::Mock` and `K8::TestApp` are removed.
|
45
|
+
Use rack-test_app gem instead.
|
46
|
+
|
47
|
+
* [bugfix] Document fixed.
|
48
|
+
|
49
|
+
* [internal] Remove `K8::ActionClassMapping`, 'K8::ActionRouter' and
|
50
|
+
'K8::ActionFinder' classes.
|
51
|
+
|
52
|
+
* [internal] Define new class `K8::ActionMapping` instead of remove classes.
|
53
|
+
|
54
|
+
|
55
|
+
Release 0.1.0 (2015-10-27)
|
56
|
+
--------------------------
|
57
|
+
|
58
|
+
* Public release
|
59
|
+
|
60
|
+
|
61
|
+
Release 0.0.1 (2015-10-26)
|
62
|
+
--------------------------
|
63
|
+
|
64
|
+
* Test release
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
$Copyright: copyright(c) 2014-
|
1
|
+
$Copyright: copyright(c) 2014-2016 kuwata-lab.com all rights reserved $
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Keight.rb README
|
2
2
|
================
|
3
3
|
|
4
|
-
($Release: 0.
|
4
|
+
($Release: 0.2.0 $)
|
5
5
|
|
6
6
|
|
7
7
|
Overview
|
@@ -18,15 +18,15 @@ Benchmarks
|
|
18
18
|
|
19
19
|
Measured with `app.call(env)` style in order to exclude server overhead:
|
20
20
|
|
21
|
-
|
|
22
|
-
|
23
|
-
| Rails
|
24
|
-
| Rails
|
25
|
-
| Sinatra
|
26
|
-
| Sinatra
|
27
|
-
| Rack
|
28
|
-
| Keight
|
29
|
-
| Keight
|
21
|
+
| Framework | Request | usec/req | req/sec |
|
22
|
+
|:----------|:-------------------|---------:|---------:|
|
23
|
+
| Rails | GET /api/hello | 738.7 | 1353.7 |
|
24
|
+
| Rails | GET /api/hello/123 | 782.2 | 1278.4 |
|
25
|
+
| Sinatra | GET /api/hello | 144.1 | 6938.3 |
|
26
|
+
| Sinatra | GET /api/hello/123 | 158.4 | 6313.8 |
|
27
|
+
| Rack | GET /api/hello | 9.9 | 101050.9 |
|
28
|
+
| Keight | GET /api/hello | 7.6 | 132432.8 |
|
29
|
+
| Keight | GET /api/hello/123 | 10.6 | 94705.9 |
|
30
30
|
|
31
31
|
* Ruby 2.2.3
|
32
32
|
* Rails 4.2.4
|
@@ -48,7 +48,7 @@ $ export GEM_HOME=$PWD/gems
|
|
48
48
|
$ export PATH=$GEM_HOME/bin:$PATH
|
49
49
|
|
50
50
|
$ gem install keight
|
51
|
-
$ vi hello.rb
|
51
|
+
$ vi hello.rb # see below
|
52
52
|
$ vi config.ru # != 'config.rb'
|
53
53
|
$ rackup -p 8000 config.ru
|
54
54
|
```
|
@@ -81,44 +81,46 @@ class HelloAction < K8::Action
|
|
81
81
|
end
|
82
82
|
```
|
83
83
|
|
84
|
-
config.
|
84
|
+
config.ru:
|
85
85
|
|
86
86
|
```ruby
|
87
87
|
# -*- coding: utf-8 -*-
|
88
88
|
require 'keight'
|
89
89
|
require './hello'
|
90
90
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
#]
|
100
|
-
#app = K8::RackApplication.new(mapping)
|
91
|
+
mapping = [
|
92
|
+
['/api', [
|
93
|
+
['/hello' , HelloAction],
|
94
|
+
## or
|
95
|
+
#['/hello' , "./hello:HelloAction"],
|
96
|
+
]],
|
97
|
+
]
|
98
|
+
app = K8::RackApplication.new(mapping)
|
101
99
|
|
102
100
|
run app
|
103
101
|
```
|
104
102
|
|
105
|
-
Open http://localhost:8000/hello or http://localhost:8000/hello/123
|
103
|
+
Open http://localhost:8000/api/hello or http://localhost:8000/api/hello/123
|
106
104
|
with your browser.
|
107
105
|
|
108
|
-
Do you like it? If so, try `k8rb
|
106
|
+
Do you like it? If so, try `k8rb project myapp1` to generate project skeleton.
|
109
107
|
|
110
108
|
```console
|
111
|
-
$
|
109
|
+
$ mkdir gems # if necessary
|
110
|
+
$ export GEM_HOME=$PWD/gems # if necessary
|
111
|
+
$ export PATH=$GEM_HOME/bin:$PATH # if necessary
|
112
|
+
$ gem install -N keight
|
113
|
+
$ k8rb help # show help
|
114
|
+
$ k8rb project myapp1 # create new project
|
112
115
|
$ cd myapp1/
|
116
|
+
$ rake setup # install gems and download libs
|
113
117
|
$ export APP_ENV=dev # 'dev', 'prod', or 'stg'
|
114
|
-
$ k8rb mapping
|
115
|
-
$ k8rb
|
116
|
-
$
|
117
|
-
$
|
118
|
-
$
|
119
|
-
|
120
|
-
$ gem install puma
|
121
|
-
$ rackup -p 8000 -E production -s puma config.ru
|
118
|
+
$ k8rb help mapping
|
119
|
+
$ k8rb mapping # list urlpath mappings
|
120
|
+
$ k8rb mapping --format=javascript # or jquery,angular,json,yaml
|
121
|
+
$ k8rb configs # list config parameters
|
122
|
+
$ rake server port=8000
|
123
|
+
$ open http://localhost:8000/
|
122
124
|
$ ab -n 10000 -c 100 http://localhost:8000/api/hello
|
123
125
|
```
|
124
126
|
|
@@ -132,8 +134,8 @@ require 'keight'
|
|
132
134
|
class HelloAction < K8::Action
|
133
135
|
|
134
136
|
## mapping
|
135
|
-
mapping '',
|
136
|
-
mapping '/{name
|
137
|
+
mapping '', :GET=>:do_hello_world
|
138
|
+
mapping '/{name:\w+}', :GET=>:do_hello
|
137
139
|
|
138
140
|
## request, response, and helpers
|
139
141
|
|
@@ -199,7 +201,7 @@ class HelloAction < K8::Action
|
|
199
201
|
end
|
200
202
|
|
201
203
|
def handle_exception(ex) # exception handler
|
202
|
-
meth = "on_#{ex.class}"
|
204
|
+
meth = "on_#{ex.class.name}"
|
203
205
|
return __send__(meth, ex) if respond_to?(meth)
|
204
206
|
super
|
205
207
|
end
|
@@ -227,6 +229,144 @@ opts = {
|
|
227
229
|
urlpath_cache_size: 0, # 0 means cache disabled
|
228
230
|
}
|
229
231
|
app = K8::RackApplication.new(urlpath_mapping, opts)
|
232
|
+
|
233
|
+
## misc
|
234
|
+
p HelloAction[:do_update].method #=> :GET
|
235
|
+
p HelloAction[:do_update].urlpath(123) #=> "/api/books/123"
|
236
|
+
p HelloAction[:do_update].form_action_attr(123)
|
237
|
+
#=> "/api/books/123?_method=PUT"
|
238
|
+
```
|
239
|
+
|
240
|
+
|
241
|
+
Topics
|
242
|
+
------
|
243
|
+
|
244
|
+
|
245
|
+
### Make Routing More Faster
|
246
|
+
|
247
|
+
Specify `urlpath_cache_size: n` (where n is 100 or so) to
|
248
|
+
`K8::RackApplication.new()`.
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
urlpath_mapping = [
|
252
|
+
....
|
253
|
+
]
|
254
|
+
rack_app = K8::RackApplication.new(urlpath_mapping,
|
255
|
+
urlpath_cache_size: 100) # !!!
|
256
|
+
```
|
257
|
+
|
258
|
+
In general, there are two type of URL path pattern: fixed and variable.
|
259
|
+
|
260
|
+
* Fixed URL path pattern doesn't contain any URL path parameter.<br>
|
261
|
+
Example: `/`, `/api/books`, `/api/books/new`.
|
262
|
+
* Variable URL path pattern contains one or more URL path parameters.<br>
|
263
|
+
Example: `/api/books/{id}`, `/api/books/new.{format:html|json}`.
|
264
|
+
|
265
|
+
Keight.rb caches fixed patterns and doesn't variable ones, therefore
|
266
|
+
routing for fixed URL path is faster than variable one.
|
267
|
+
|
268
|
+
If `urlpath_cache_size: n` is specified, Keight.rb caches latest `n` entries
|
269
|
+
of request path matched to variable URL path pattern.
|
270
|
+
This will make routing for variable one much faster.
|
271
|
+
|
272
|
+
|
273
|
+
### Default Pattern of URL Path Parameter
|
274
|
+
|
275
|
+
URL path parameter `{id}` and `{xxx_id}` are regarded as `{id:\d+}` and
|
276
|
+
`{xxx_id:\d+}` respectively and converted into positive interger automatically.
|
277
|
+
For example:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
class BooksAction < K8::Action
|
281
|
+
mapping '/{id}', :GET=>:do_show
|
282
|
+
def do_show(id)
|
283
|
+
p id.class #=> Fixnum
|
284
|
+
....
|
285
|
+
end
|
286
|
+
end
|
287
|
+
```
|
288
|
+
|
289
|
+
URL path parameter `{date}` and `{xxx_date}` are regarded as
|
290
|
+
`{date:\d\d\d\d-\d\d-\d\d}` and `{xxx_date:\d\d\d\d-\d\d-\d\d}` respectively
|
291
|
+
and converted into Date object automatically.
|
292
|
+
For example:
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
class BlogAPI < K8::Action
|
296
|
+
mapping '/{date}', :GET=>:list_entries
|
297
|
+
def list_entries(date)
|
298
|
+
p date.class #=> Date
|
299
|
+
....
|
300
|
+
end
|
301
|
+
end
|
302
|
+
```
|
303
|
+
|
304
|
+
**If you specify `{id:\d+}` or `{date:\d\d\d\d-\d\d-\d\d}` explicitly,
|
305
|
+
URL path parameter value is not converted into integer nor Date object.**
|
306
|
+
In other words, you can cancel automatic conversion by specifing regular
|
307
|
+
expression of URL path parameters.
|
308
|
+
|
309
|
+
|
310
|
+
### Nested Routing
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
urlpath_mapping = [
|
314
|
+
['/api', [
|
315
|
+
['/books' , BookAPI],
|
316
|
+
['/books/{book_id}/comments' , BookCommentsAPI],
|
317
|
+
]],
|
318
|
+
]
|
319
|
+
```
|
320
|
+
|
321
|
+
|
322
|
+
### URL Path Helpers
|
323
|
+
|
324
|
+
```ruby
|
325
|
+
p BooksAPI[:do_index].method #=> :GET
|
326
|
+
p BooksAPI[:do_index].urlpath() #=> "/api/books"
|
327
|
+
|
328
|
+
p BooksAPI[:do_update].method #=> :PUT
|
329
|
+
p BooksAPI[:do_update].urlpath(123) #=> "/api/books/123"
|
330
|
+
p BooksAPI[:do_update].form_action_attr(123) #=> "/api/books/123?_method=PUT"
|
331
|
+
```
|
332
|
+
|
333
|
+
(Notice that these are availabe after `K8::RackApplication` object is created.)
|
334
|
+
|
335
|
+
|
336
|
+
### Routing for JavaScript
|
337
|
+
|
338
|
+
Keight.rb can generate JavaScript routing file.
|
339
|
+
|
340
|
+
```console
|
341
|
+
$ k8rb project myapp1
|
342
|
+
$ cd myapp1/
|
343
|
+
$ k8rb mapping --format=javascript | less # or 'jquery', 'angular'
|
344
|
+
$ mkdir -p static/js
|
345
|
+
$ jsfile=static/js/urlpath_mapping.js
|
346
|
+
$ rm -f $jsfile
|
347
|
+
$ echo 'var Mapping = {' >> $jsfile
|
348
|
+
$ k8rb mapping --format=javascript >> $jsfile
|
349
|
+
$ echo '};' >> $jsfile
|
350
|
+
```
|
351
|
+
|
352
|
+
|
353
|
+
### Download JavaScript Libraries
|
354
|
+
|
355
|
+
Keight.rb can download Javascript or CSS libraries from [cdnjs.com].
|
356
|
+
It is good idea to make layout of JavaScript libraries to be same as CDN.
|
357
|
+
|
358
|
+
[cdnjs.com]: https://cdnjs.com/
|
359
|
+
|
360
|
+
```console
|
361
|
+
$ k8rb project myapp1
|
362
|
+
$ cd myapp1/
|
363
|
+
$ k8rb help cdnjs
|
364
|
+
$ k8rb cdnjs # list libraries
|
365
|
+
$ k8rb cdnjs 'jquery*' # search libraries
|
366
|
+
$ k8rb cdnjs jquery # list versions
|
367
|
+
$ k8rb cdnjs jquery 2.1.4 # download library
|
368
|
+
## or
|
369
|
+
$ k8rb cdnjs --basedir=static/lib jquery 2.1.4
|
230
370
|
```
|
231
371
|
|
232
372
|
|
@@ -242,17 +382,17 @@ I don't think Keight.rb is so fast. Other frameworks are just too slow.
|
|
242
382
|
|
243
383
|
#### How to setup template engine?
|
244
384
|
|
245
|
-
Try `k8rb
|
385
|
+
Try `k8rb project myapp1; cd myapp1; less app/action.rb`.
|
246
386
|
|
247
387
|
|
248
388
|
#### How to support static files?
|
249
389
|
|
250
|
-
Try `k8rb
|
390
|
+
Try `k8rb project myapp1; cd myapp1; less app/action.rb`.
|
251
391
|
|
252
392
|
|
253
393
|
#### How to setup session?
|
254
394
|
|
255
|
-
Try `k8rb
|
395
|
+
Try `k8rb project myapp1; cd myapp1; less config.ru`.
|
256
396
|
|
257
397
|
|
258
398
|
#### Can I use Rack::Request and Rack::Response instead of Keight's?
|
@@ -260,24 +400,9 @@ Try `k8rb init myapp1; cd myapp1; less config.ru`.
|
|
260
400
|
Try `K8::REQUEST_CLASS = Rack::Request; K8::RESPONSE_CLASS = Rack::Response`.
|
261
401
|
|
262
402
|
|
263
|
-
#### What `urlpath_cache_size: 0` means?
|
264
|
-
|
265
|
-
`K8::RackApplication` can take `urlpath_cache_size: n` keyword arugment.
|
266
|
-
|
267
|
-
* If `n == 0` then Keight.rb doesn't cache urlpath mapping containig
|
268
|
-
urlpath parameters such as `/api/books/{id}`.
|
269
|
-
* If `n > 0` then Keight.rb caches latest `n` entries of urlpath mapping
|
270
|
-
containing urlpath parameters.
|
271
|
-
* Keight.rb always caches urlpath mapping which has no urlpath parameters.
|
272
|
-
For example, `/api/books` is always cached regardless
|
273
|
-
`urlpath_cache_size:` value.
|
274
|
-
|
275
|
-
If you need more performance, try `urlpath_cache_size: 1000` or so.
|
276
|
-
|
277
|
-
|
278
403
|
License and Copyright
|
279
404
|
---------------------
|
280
405
|
|
281
406
|
$License: MIT License $
|
282
407
|
|
283
|
-
$Copyright: copyright(c) 2014-
|
408
|
+
$Copyright: copyright(c) 2014-2016 kuwata-lab.com all rights reserved $
|
data/Rakefile
CHANGED
data/bench/bench.rb
CHANGED
@@ -2,13 +2,31 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH << '.'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def _version(cmdopt)
|
6
|
+
if cmdopt == '0'
|
7
|
+
return nil
|
8
|
+
end
|
9
|
+
begin
|
10
|
+
return yield
|
11
|
+
rescue LoadError
|
12
|
+
if cmdopt.to_s.empty?
|
13
|
+
return nil
|
14
|
+
else
|
15
|
+
raise
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
version_rack = _version($rack) { require 'rack' ; Rack.release }
|
21
|
+
version_sina = _version($sina) { require 'sinatra/base' ; Sinatra::VERSION }
|
22
|
+
version_mplx = _version($mplx) { require 'rack/multiplexer'; Rack::Multiplexer::VERSION }
|
23
|
+
version_k8 = _version($k8 ) { require 'keight' ; K8::RELEASE }
|
24
|
+
version_jet = _version($jet ) { require 'rack/jet_router' ; Rack::JetRouter::RELEASE }
|
9
25
|
|
26
|
+
$api_entries = ('a'..'z').each_with_index.map {|x, i| "%s%02d" % [x*3, i+1] }
|
10
27
|
|
11
|
-
|
28
|
+
|
29
|
+
if version_rack
|
12
30
|
|
13
31
|
class RackApp1
|
14
32
|
def call(env)
|
@@ -48,14 +66,15 @@ if defined?(Rack)
|
|
48
66
|
end
|
49
67
|
|
50
68
|
|
51
|
-
|
52
|
-
$admin_entries = ('a'..'z').each_with_index.collect {|c,i| "%s%02d" % [c*3, i+1] }
|
53
|
-
|
54
|
-
|
55
|
-
if defined?(Sinatra)
|
69
|
+
if version_sina
|
56
70
|
|
57
71
|
class SinaApp < Sinatra::Base
|
58
72
|
|
73
|
+
set :sessions , false
|
74
|
+
set :logging , false
|
75
|
+
set :protection , false
|
76
|
+
set :x_cascade , false
|
77
|
+
|
59
78
|
for x in $api_entries
|
60
79
|
get "/api/#{x}" do "<h1>index</h1>" end
|
61
80
|
post "/api/#{x}" do "<h1>create</h1>" end
|
@@ -66,14 +85,6 @@ if defined?(Sinatra)
|
|
66
85
|
#get "/api/#{x}/:id/edit" do "<h1>edit</h1>" end
|
67
86
|
end
|
68
87
|
|
69
|
-
for x in $admin_entries # 'aaa01', 'bbb02', ..., 'zzz26'
|
70
|
-
get "/admin/#{x}" do '<p>index</p>' end
|
71
|
-
post "/admin/#{x}" do '<p>create</p>' end
|
72
|
-
get "/admin/#{x}/:id" do '<p>show</p>' end
|
73
|
-
put "/admin/#{x}/:id" do '<p>update</p>' end
|
74
|
-
delete "/admin/#{x}/:id" do '<p>delete</p>' end
|
75
|
-
end
|
76
|
-
|
77
88
|
end
|
78
89
|
|
79
90
|
sina_app = SinaApp.new
|
@@ -81,67 +92,35 @@ if defined?(Sinatra)
|
|
81
92
|
end
|
82
93
|
|
83
94
|
|
84
|
-
if
|
85
|
-
|
86
|
-
mplx_dummy = proc {|env|
|
87
|
-
[200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
|
88
|
-
#req = Rack::Request.new(env)
|
89
|
-
#resp = Rack::Response.new
|
90
|
-
#[resp.status, resp.headers, ["<h1>index</h1>"]]
|
91
|
-
}
|
92
|
-
|
93
|
-
mplx_app1 = Rack::Multiplexer.new
|
94
|
-
|
95
|
-
for x in $api_entries
|
96
|
-
mplx_app1.get "/api/#{x}", mplx_dummy
|
97
|
-
mplx_app1.post "/api/#{x}", mplx_dummy
|
98
|
-
#mplx_app1.get "/api/#{x}/new", mplx_dummy
|
99
|
-
mplx_app1.get "/api/#{x}/:id", mplx_dummy
|
100
|
-
mplx_app1.post "/api/#{x}/:id", mplx_dummy
|
101
|
-
mplx_app1.delete "/api/#{x}/:id", mplx_dummy
|
102
|
-
#mplx_app1.get "/api/#{x}/:id/edit", mplx_dummy
|
103
|
-
end
|
104
|
-
for x in $admin_entries # 'aaa01', 'bbb02', ..., 'zzz26'
|
105
|
-
mplx_app1.get "/admin/#{x}", mplx_dummy
|
106
|
-
mplx_app1.post "/admin/#{x}", mplx_dummy
|
107
|
-
mplx_app1.get "/admin/#{x}/:id", mplx_dummy
|
108
|
-
mplx_app1.put "/admin/#{x}/:id", mplx_dummy
|
109
|
-
mplx_app1.delete "/admin/#{x}/:id", mplx_dummy
|
110
|
-
end
|
95
|
+
if version_mplx
|
111
96
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
mplx_app2 = proc {|env|
|
131
|
-
urlpath = env['PATH_INFO']
|
132
|
-
if urlpath.start_with?('/api')
|
133
|
-
mplx_api.call(env)
|
134
|
-
elsif urlpath.start_with?('/admin')
|
135
|
-
mplx_admin.call(env)
|
136
|
-
else
|
137
|
-
[404, {}, []]
|
97
|
+
mplx_app = proc {
|
98
|
+
#
|
99
|
+
proc_ = proc {|env|
|
100
|
+
[200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
|
101
|
+
#req = Rack::Request.new(env)
|
102
|
+
#resp = Rack::Response.new
|
103
|
+
#[resp.status, resp.headers, ["<h1>index</h1>"]]
|
104
|
+
}
|
105
|
+
#
|
106
|
+
app = Rack::Multiplexer.new
|
107
|
+
for x in $api_entries
|
108
|
+
app.get "/api/#{x}", proc_
|
109
|
+
app.post "/api/#{x}", proc_
|
110
|
+
#app.get "/api/#{x}/new", proc_
|
111
|
+
app.get "/api/#{x}/:id", proc_
|
112
|
+
app.post "/api/#{x}/:id", proc_
|
113
|
+
app.delete "/api/#{x}/:id", proc_
|
114
|
+
#app.get "/api/#{x}/:id/edit", proc_
|
138
115
|
end
|
139
|
-
|
116
|
+
#
|
117
|
+
app
|
118
|
+
}.call()
|
140
119
|
|
141
120
|
end
|
142
121
|
|
143
122
|
|
144
|
-
if
|
123
|
+
if version_k8
|
145
124
|
|
146
125
|
class DummyAction < K8::Action
|
147
126
|
mapping '', :GET=>:do_index, :POST=>:do_create
|
@@ -157,37 +136,59 @@ if defined?(K8)
|
|
157
136
|
def do_edit(id) ; "<h1>edit</h1>"; end
|
158
137
|
end
|
159
138
|
#
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
139
|
+
k8_app = proc {
|
140
|
+
mapping = [
|
141
|
+
['/api', $api_entries.map {|x| ["/#{x}", DummyAction] }],
|
142
|
+
]
|
143
|
+
opts = {
|
144
|
+
urlpath_cache_size: ($k8size || 0).to_i,
|
145
|
+
enable_urlpath_param_range: $k8range != '0',
|
146
|
+
}
|
147
|
+
K8::RackApplication.new(mapping, opts)
|
148
|
+
}.call()
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
if version_jet
|
154
|
+
|
155
|
+
jet_app = proc {
|
156
|
+
#
|
157
|
+
jet_proc = proc {|env|
|
158
|
+
[200, {"Content-Type"=>"text/html"}, ["<h1>hello</h1>"]]
|
159
|
+
#req = Rack::Request.new(env)
|
160
|
+
#resp = Rack::Response.new
|
161
|
+
#[resp.status, resp.headers, ["<h1>index</h1>"]]
|
162
|
+
}
|
163
|
+
methods1 = {:GET=>jet_proc, :POST=>jet_proc}
|
164
|
+
methods2 = {:GET=>jet_proc, :PUT=>jet_proc, :DELETE=>jet_proc}
|
165
|
+
#
|
166
|
+
arr = $api_entries.map {|x| ["/#{x}", [['', methods1], ['/:id', methods2]]] }
|
167
|
+
jet_mapping = [
|
168
|
+
['/api', $api_entries.map {|x| ["/#{x}", [
|
169
|
+
['', methods1],
|
170
|
+
['/:id', methods2],
|
171
|
+
]] }
|
172
|
+
],
|
173
|
+
]
|
174
|
+
#
|
175
|
+
jet_opts = {
|
176
|
+
urlpath_cache_size: ($jetcache || 0).to_i,
|
177
|
+
enable_urlpath_param_range: $jetrange != '0',
|
178
|
+
}
|
179
|
+
#
|
180
|
+
Rack::JetRouter.new(jet_mapping, jet_opts)
|
181
|
+
}.call()
|
180
182
|
|
181
183
|
end
|
182
184
|
|
183
185
|
|
184
186
|
def _chk(tuple)
|
185
187
|
tuple[0] == 200 or raise "200 expected but got #{tuple[0]}"
|
186
|
-
GC.start
|
187
188
|
end
|
188
189
|
|
189
|
-
|
190
|
-
$environ
|
190
|
+
require 'rack' unless defined?(Rack)
|
191
|
+
$environ = Rack::MockRequest.env_for("http://localhost/", method: 'GET')
|
191
192
|
|
192
193
|
def newenv(path)
|
193
194
|
env = $environ.dup
|
@@ -198,21 +199,27 @@ end
|
|
198
199
|
|
199
200
|
require 'benchmarker'
|
200
201
|
|
202
|
+
N = ($N || 100000).to_i
|
201
203
|
|
202
|
-
Benchmarker.new(:width=>30, :loop=>
|
203
|
-
|
204
|
-
flag_rack = flag_sinatra = flag_multiplexer = flag_keight = false
|
205
|
-
flag_rack = defined?(Rack)
|
206
|
-
#flag_sinatra = defined?(Sinatra)
|
207
|
-
flag_multiplexer = defined?(Rack::Multiplexer)
|
208
|
-
flag_keight = defined?(K8)
|
209
|
-
|
210
|
-
urlpaths = %w[/api/books /api/books/123 /api/support /api/support/123
|
211
|
-
/admin/aaa01 /admin/aaa01/123 /admin/zzz26 /admin/zzz26/123]
|
204
|
+
Benchmarker.new(:width=>30, :loop=>N) do |bm|
|
212
205
|
|
206
|
+
urlpaths = [
|
207
|
+
'/api/aaa01',
|
208
|
+
'/api/aaa01/123',
|
209
|
+
'/api/zzz26',
|
210
|
+
'/api/zzz26/789',
|
211
|
+
]
|
213
212
|
|
214
213
|
tuple = nil
|
215
214
|
|
215
|
+
puts ""
|
216
|
+
puts "** rack : #{version_rack || '-'}"
|
217
|
+
puts "** rack-jet_router : #{version_jet || '-'}"
|
218
|
+
puts "** rack-multiplexer: #{version_mplx || '-'}"
|
219
|
+
puts "** sinatra : #{version_sina || '-'}"
|
220
|
+
puts "** keight : #{version_k8 || '-'}"
|
221
|
+
puts ""
|
222
|
+
puts "** N=#{N}"
|
216
223
|
|
217
224
|
### empty task
|
218
225
|
|
@@ -222,10 +229,11 @@ Benchmarker.new(:width=>30, :loop=>100000) do |bm|
|
|
222
229
|
|
223
230
|
|
224
231
|
### Rack
|
225
|
-
if
|
232
|
+
if version_rack
|
233
|
+
rack_labels = ['Rack', 'R:Rq', 'R:Rs', 'RqRs']
|
226
234
|
rack_apps = [rack_app1, rack_app2, rack_app3, rack_app4]
|
227
|
-
for rack_app,
|
228
|
-
bm.task("(
|
235
|
+
for rack_app, label in rack_apps.zip(rack_labels)
|
236
|
+
bm.task("(#{label}) /some/where") do
|
229
237
|
tuple = rack_app.call(newenv("/some/where"))
|
230
238
|
end
|
231
239
|
_chk(tuple)
|
@@ -234,7 +242,7 @@ Benchmarker.new(:width=>30, :loop=>100000) do |bm|
|
|
234
242
|
|
235
243
|
|
236
244
|
### Sinatra
|
237
|
-
if
|
245
|
+
if version_sina
|
238
246
|
for upath in urlpaths
|
239
247
|
bm.task("(Sina) #{upath}") do
|
240
248
|
tuple = sina_app.call(newenv(upath))
|
@@ -245,34 +253,126 @@ Benchmarker.new(:width=>30, :loop=>100000) do |bm|
|
|
245
253
|
|
246
254
|
|
247
255
|
### Rack::Multiplexer
|
248
|
-
if
|
256
|
+
if version_mplx
|
249
257
|
for upath in urlpaths
|
250
258
|
bm.task("(Mplx) #{upath}") do
|
251
|
-
tuple =
|
259
|
+
tuple = mplx_app.call(newenv(upath))
|
252
260
|
end
|
253
261
|
_chk(tuple)
|
254
262
|
end
|
255
263
|
end
|
256
264
|
|
257
|
-
|
265
|
+
|
266
|
+
### Keight
|
267
|
+
|
268
|
+
if version_k8
|
258
269
|
for upath in urlpaths
|
259
|
-
bm.task("(
|
260
|
-
tuple =
|
270
|
+
bm.task("(K8 ) #{upath}") do
|
271
|
+
tuple = k8_app.call(newenv(upath))
|
261
272
|
end
|
262
273
|
_chk(tuple)
|
263
274
|
end
|
264
275
|
end
|
265
276
|
|
266
277
|
|
267
|
-
###
|
278
|
+
### Rack::JetRouter
|
268
279
|
|
269
|
-
if
|
280
|
+
if version_jet
|
270
281
|
for upath in urlpaths
|
271
|
-
bm.task("(
|
272
|
-
tuple =
|
282
|
+
bm.task("(JetR) #{upath}") do
|
283
|
+
tuple = jet_app.call(newenv(upath))
|
273
284
|
end
|
274
285
|
_chk(tuple)
|
275
286
|
end
|
276
287
|
end
|
277
288
|
|
278
289
|
end
|
290
|
+
|
291
|
+
|
292
|
+
__END__
|
293
|
+
|
294
|
+
###
|
295
|
+
### Example result
|
296
|
+
###
|
297
|
+
|
298
|
+
$ ruby -I../lib -I. -s bench.rb -N=1000000
|
299
|
+
|
300
|
+
benchmarker.rb: release 0.0.0
|
301
|
+
RUBY_VERSION: 2.3.0
|
302
|
+
RUBY_PATCHLEVEL: 0
|
303
|
+
RUBY_PLATFORM: x86_64-darwin15
|
304
|
+
|
305
|
+
** rack : 1.6.4
|
306
|
+
** rack-jet_router : 1.1.0
|
307
|
+
** rack-multiplexer: 0.0.8
|
308
|
+
** sinatra : 1.4.6
|
309
|
+
** keight : 0.2.0
|
310
|
+
|
311
|
+
** N=1000000
|
312
|
+
|
313
|
+
## user sys total real
|
314
|
+
(Empty) 7.3000 0.0900 7.3900 7.4131
|
315
|
+
(Rack) /some/where 0.8400 -0.0400 0.8000 0.7903
|
316
|
+
(R:Rq) /some/where 0.8400 -0.0500 0.7900 0.7743
|
317
|
+
(R:Rs) /some/where 6.1600 -0.0500 6.1100 6.0898
|
318
|
+
(RqRs) /some/where 6.4200 -0.0600 6.3600 6.3407
|
319
|
+
(Sina) /api/aaa01 84.5700 18.0800 102.6500 102.7069
|
320
|
+
(Sina) /api/aaa01/123 94.1300 18.4800 112.6100 112.6892
|
321
|
+
(Sina) /api/zzz26 125.7300 19.0800 144.8100 145.0454
|
322
|
+
(Sina) /api/zzz26/789 133.8000 18.9600 152.7600 152.9070
|
323
|
+
(Mplx) /api/aaa01 5.0200 0.1700 5.1900 5.1821
|
324
|
+
(Mplx) /api/aaa01/123 16.7100 0.3100 17.0200 17.0086
|
325
|
+
(Mplx) /api/zzz26 23.3700 -0.0400 23.3300 23.3190
|
326
|
+
(Mplx) /api/zzz26/789 35.6500 0.0100 35.6600 35.6661
|
327
|
+
(K8 ) /api/aaa01 5.9200 0.0300 5.9500 5.9423
|
328
|
+
(K8 ) /api/aaa01/123 9.2200 0.0900 9.3100 9.2934
|
329
|
+
(K8 ) /api/zzz26 6.2700 0.0600 6.3300 6.3158
|
330
|
+
(K8 ) /api/zzz26/789 10.0300 0.1300 10.1600 10.1547
|
331
|
+
(JetR) /api/aaa01 1.1800 0.0400 1.2200 1.2154
|
332
|
+
(JetR) /api/aaa01/123 5.0400 0.1100 5.1500 5.1431
|
333
|
+
(JetR) /api/zzz26 0.9600 0.0300 0.9900 0.9681
|
334
|
+
(JetR) /api/zzz26/789 5.6900 0.1100 5.8000 5.7946
|
335
|
+
|
336
|
+
## Ranking real
|
337
|
+
(R:Rq) /some/where 0.7743 (100.0%) ********************
|
338
|
+
(Rack) /some/where 0.7903 ( 98.0%) ********************
|
339
|
+
(JetR) /api/zzz26 0.9681 ( 80.0%) ****************
|
340
|
+
(JetR) /api/aaa01 1.2154 ( 63.7%) *************
|
341
|
+
(JetR) /api/aaa01/123 5.1431 ( 15.1%) ***
|
342
|
+
(Mplx) /api/aaa01 5.1821 ( 14.9%) ***
|
343
|
+
(JetR) /api/zzz26/789 5.7946 ( 13.4%) ***
|
344
|
+
(K8 ) /api/aaa01 5.9423 ( 13.0%) ***
|
345
|
+
(R:Rs) /some/where 6.0898 ( 12.7%) ***
|
346
|
+
(K8 ) /api/zzz26 6.3158 ( 12.3%) **
|
347
|
+
(RqRs) /some/where 6.3407 ( 12.2%) **
|
348
|
+
(K8 ) /api/aaa01/123 9.2934 ( 8.3%) **
|
349
|
+
(K8 ) /api/zzz26/789 10.1547 ( 7.6%) **
|
350
|
+
(Mplx) /api/aaa01/123 17.0086 ( 4.6%) *
|
351
|
+
(Mplx) /api/zzz26 23.3190 ( 3.3%) *
|
352
|
+
(Mplx) /api/zzz26/789 35.6661 ( 2.2%)
|
353
|
+
(Sina) /api/aaa01 102.7069 ( 0.8%)
|
354
|
+
(Sina) /api/aaa01/123 112.6892 ( 0.7%)
|
355
|
+
(Sina) /api/zzz26 145.0454 ( 0.5%)
|
356
|
+
(Sina) /api/zzz26/789 152.9070 ( 0.5%)
|
357
|
+
|
358
|
+
## Matrix real [01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]
|
359
|
+
[01] (Rack2) /some/where 0.7743 100.0% 102.1% 125.0% 157.0% 664.2% 669.2% 748.3% 767.4% 786.5% 815.6% 818.9% 1200.2% 1311.4% 2196.6% 3011.5% 4606.1% 13264.0% 14553.1% 18731.7% 19747.0%
|
360
|
+
[02] (Rack1) /some/where 0.7903 98.0% 100.0% 122.5% 153.8% 650.7% 655.7% 733.2% 751.9% 770.5% 799.1% 802.3% 1175.9% 1284.8% 2152.1% 2950.5% 4512.7% 12995.2% 14258.3% 18352.2% 19346.9%
|
361
|
+
[03] (JetR) /api/zzz26 0.9681 80.0% 81.6% 100.0% 125.5% 531.2% 535.3% 598.5% 613.8% 629.0% 652.4% 654.9% 959.9% 1048.9% 1756.9% 2408.7% 3684.0% 10608.8% 11639.9% 14982.1% 15794.1%
|
362
|
+
[04] (JetR) /api/aaa01 1.2154 63.7% 65.0% 79.7% 100.0% 423.2% 426.4% 476.8% 488.9% 501.0% 519.6% 521.7% 764.6% 835.5% 1399.4% 1918.6% 2934.5% 8450.4% 9271.7% 11933.8% 12580.6%
|
363
|
+
[05] (JetR) /api/aaa01/123 5.1431 15.1% 15.4% 18.8% 23.6% 100.0% 100.8% 112.7% 115.5% 118.4% 122.8% 123.3% 180.7% 197.4% 330.7% 453.4% 693.5% 1997.0% 2191.1% 2820.2% 2973.1%
|
364
|
+
[06] (Mplx) /api/aaa01 5.1821 14.9% 15.3% 18.7% 23.5% 99.2% 100.0% 111.8% 114.7% 117.5% 121.9% 122.4% 179.3% 196.0% 328.2% 450.0% 688.3% 1982.0% 2174.6% 2799.0% 2950.7%
|
365
|
+
[07] (JetR) /api/zzz26/789 5.7946 13.4% 13.6% 16.7% 21.0% 88.8% 89.4% 100.0% 102.5% 105.1% 109.0% 109.4% 160.4% 175.2% 293.5% 402.4% 615.5% 1772.5% 1944.7% 2503.1% 2638.8%
|
366
|
+
[08] (K8) /api/aaa01 5.9423 13.0% 13.3% 16.3% 20.5% 86.6% 87.2% 97.5% 100.0% 102.5% 106.3% 106.7% 156.4% 170.9% 286.2% 392.4% 600.2% 1728.4% 1896.4% 2440.9% 2573.2%
|
367
|
+
[09] (Rack3) /some/where 6.0898 12.7% 13.0% 15.9% 20.0% 84.5% 85.1% 95.2% 97.6% 100.0% 103.7% 104.1% 152.6% 166.7% 279.3% 382.9% 585.7% 1686.5% 1850.5% 2381.8% 2510.9%
|
368
|
+
[10] (K8) /api/zzz26 6.3158 12.3% 12.5% 15.3% 19.2% 81.4% 82.0% 91.7% 94.1% 96.4% 100.0% 100.4% 147.1% 160.8% 269.3% 369.2% 564.7% 1626.2% 1784.3% 2296.6% 2421.0%
|
369
|
+
[11] (Rack4) /some/where 6.3407 12.2% 12.5% 15.3% 19.2% 81.1% 81.7% 91.4% 93.7% 96.0% 99.6% 100.0% 146.6% 160.2% 268.2% 367.8% 562.5% 1619.8% 1777.2% 2287.5% 2411.5%
|
370
|
+
[12] (K8) /api/aaa01/123 9.2934 8.3% 8.5% 10.4% 13.1% 55.3% 55.8% 62.4% 63.9% 65.5% 68.0% 68.2% 100.0% 109.3% 183.0% 250.9% 383.8% 1105.2% 1212.6% 1560.7% 1645.3%
|
371
|
+
[13] (K8) /api/zzz26/789 10.1547 7.6% 7.8% 9.5% 12.0% 50.6% 51.0% 57.1% 58.5% 60.0% 62.2% 62.4% 91.5% 100.0% 167.5% 229.6% 351.2% 1011.4% 1109.7% 1428.4% 1505.8%
|
372
|
+
[14] (Mplx) /api/aaa01/123 17.0086 4.6% 4.6% 5.7% 7.1% 30.2% 30.5% 34.1% 34.9% 35.8% 37.1% 37.3% 54.6% 59.7% 100.0% 137.1% 209.7% 603.9% 662.5% 852.8% 899.0%
|
373
|
+
[15] (Mplx) /api/zzz26 23.3190 3.3% 3.4% 4.2% 5.2% 22.1% 22.2% 24.8% 25.5% 26.1% 27.1% 27.2% 39.9% 43.5% 72.9% 100.0% 152.9% 440.4% 483.3% 622.0% 655.7%
|
374
|
+
[16] (Mplx) /api/zzz26/789 35.6661 2.2% 2.2% 2.7% 3.4% 14.4% 14.5% 16.2% 16.7% 17.1% 17.7% 17.8% 26.1% 28.5% 47.7% 65.4% 100.0% 288.0% 316.0% 406.7% 428.7%
|
375
|
+
[17] (Sina) /api/aaa01 102.7069 0.8% 0.8% 0.9% 1.2% 5.0% 5.0% 5.6% 5.8% 5.9% 6.1% 6.2% 9.0% 9.9% 16.6% 22.7% 34.7% 100.0% 109.7% 141.2% 148.9%
|
376
|
+
[18] (Sina) /api/aaa01/123 112.6892 0.7% 0.7% 0.9% 1.1% 4.6% 4.6% 5.1% 5.3% 5.4% 5.6% 5.6% 8.2% 9.0% 15.1% 20.7% 31.6% 91.1% 100.0% 128.7% 135.7%
|
377
|
+
[19] (Sina) /api/zzz26 145.0454 0.5% 0.5% 0.7% 0.8% 3.5% 3.6% 4.0% 4.1% 4.2% 4.4% 4.4% 6.4% 7.0% 11.7% 16.1% 24.6% 70.8% 77.7% 100.0% 105.4%
|
378
|
+
[20] (Sina) /api/zzz26/789 152.9070 0.5% 0.5% 0.6% 0.8% 3.4% 3.4% 3.8% 3.9% 4.0% 4.1% 4.1% 6.1% 6.6% 11.1% 15.3% 23.3% 67.2% 73.7% 94.9% 100.0%
|