keight 0.1.0 → 0.2.0
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.
- 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%
|