nyny 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +18 -3
  3. data/Performance.md +34 -63
  4. data/README.md +130 -76
  5. data/benchmark.rb +95 -0
  6. data/lib/nyny.rb +17 -1
  7. data/lib/nyny/app.rb +7 -3
  8. data/lib/nyny/core-ext/runner.rb +2 -1
  9. data/lib/nyny/{route_signature.rb → route.rb} +13 -8
  10. data/lib/nyny/router.rb +10 -18
  11. data/lib/nyny/version.rb +1 -1
  12. data/nyny.gemspec +1 -1
  13. data/spec/app_spec.rb +28 -3
  14. data/spec/nyny_spec.rb +11 -0
  15. data/spec/runner_spec.rb +6 -0
  16. data/spec/spec_helper.rb +1 -0
  17. metadata +6 -36
  18. data/benchmarks/filters/nyny.rb +0 -18
  19. data/benchmarks/filters/sinatra.rb +0 -17
  20. data/benchmarks/helpers/nyny.rb +0 -19
  21. data/benchmarks/helpers/sinatra.rb +0 -18
  22. data/benchmarks/simple/nyny.rb +0 -10
  23. data/benchmarks/simple/sinatra.rb +0 -9
  24. data/benchmarks/url_pattern/nyny.rb +0 -10
  25. data/benchmarks/url_pattern/sinatra.rb +0 -8
  26. data/examples/active_record/.gitignore +0 -1
  27. data/examples/active_record/Gemfile +0 -15
  28. data/examples/active_record/Rakefile +0 -51
  29. data/examples/active_record/config/database.yml +0 -0
  30. data/examples/active_record/database.rb +0 -13
  31. data/examples/active_record/db/migrate/20130606133756_add_shouts.rb +0 -12
  32. data/examples/active_record/models/shout.rb +0 -3
  33. data/examples/active_record/server.rb +0 -43
  34. data/examples/data_mapper/Gemfile +0 -7
  35. data/examples/data_mapper/database.rb +0 -7
  36. data/examples/data_mapper/db/.gitignore +0 -1
  37. data/examples/data_mapper/models/shout.rb +0 -7
  38. data/examples/data_mapper/server.rb +0 -41
  39. data/examples/json_api.rb +0 -21
  40. data/examples/templates/server.rb +0 -28
  41. data/examples/templates/views/index.haml +0 -1
  42. data/examples/web_sockets/Gemfile +0 -4
  43. data/examples/web_sockets/public/FABridge.js +0 -604
  44. data/examples/web_sockets/public/WebSocketMain.swf +0 -0
  45. data/examples/web_sockets/public/index.html +0 -76
  46. data/examples/web_sockets/public/swfobject.js +0 -4
  47. data/examples/web_sockets/public/web_socket.js +0 -388
  48. data/examples/web_sockets/server.rb +0 -60
  49. data/spec/route_signature_spec.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa8bdccd5f35a66eaa05e512117950e230350185
4
- data.tar.gz: 9932d345a2b696477bb9eef615671ce9db598de1
3
+ metadata.gz: bd3b0074fdefc837e7c08f4c760b894165bf2755
4
+ data.tar.gz: 4e7162b95bfbc2350f6f4cdccf36597ecf19ac8b
5
5
  SHA512:
6
- metadata.gz: 941652c537350c79204235b9d62af1dd7a55f0e2074a4c75043fad5f793c5ec87c1f85f6d02ec28d7df3286ac56270b1f2d7aaef07f272d5480ae6f13db3ea27
7
- data.tar.gz: a4a63feaf107bc95a0981f7b087c2a1e03d918bcf63fc1fbe23d3bf3e059a39b3124f3f8c5582fc03563deb4ca3866e3542f1803d6ca58186e03a36954aafb6f
6
+ metadata.gz: c3dc84c5a09a7dbb15ea47c52e55ff9679a473ad1241872fa81c44582ba0b3efe339f1cc1700a3dd29416191f221f58f2c926a0254cff08367dfcd50d5b59a8b
7
+ data.tar.gz: 963aac17eefd5aa6d1b67fdacddba1fb4bd0e91c14a104739921701307792968f8a4d5011f568ba12a900598e30e8386286babb6c468232c01cf1a3a84be6426
data/CHANGELOG CHANGED
@@ -1,9 +1,24 @@
1
+ 2.1.0
2
+ - Add ability to define helpers with a block
3
+ - Remove benchmark folder, and create a single benchmark file which can be
4
+ executed easily
5
+ - Simplified and optimized routing logic
6
+ - Fixed root path processing when a NYNY app is mounted
7
+ - Added Rails interop example
8
+ - Added session example
9
+ - Added NYNY.root
10
+ - Added NYNY.env
11
+ - NYNY will not show exceptions in production env
12
+
1
13
  2.0.0
2
14
  - Simplified and improved RouteSignature implementation
3
15
  - Simplified and improved RequestScope implementation
4
16
  - Made response object available in RequestScope
5
- - removed .use_protection! (the rack-protection) middleware can be easily
6
- used manually
7
- - add .register, which registers an extension (works the same way as in sinatra)
17
+ - removed .use_protection! (the rack-protection middleware can be easily
18
+ used manually)
19
+ - added support for extensions (using .register, which works the same way as in sinatra)
20
+
21
+ 1.0.2
22
+ - Add rack to runtime deps (@etehtsea)
8
23
 
9
24
  1.0.0 Initial release
@@ -1,73 +1,44 @@
1
- # NYNY vs Sinatra performance test
1
+ This output was generated by running benchmark.rb in repo root
2
2
 
3
- Note: all the tests below were made using Thin as a webserver. Httperf was
4
- choosen as the tool to do that. Bench settings: `--num-conns 10000`
3
+ Comparing NYNY 2.1.0 with Sinatra 1.4.3
5
4
 
6
- Hardware: Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz, 6 GB DDR3
7
-
8
- If you have a clue how to make proper benchmarks (because, frankly, I don't), I am open to suggestions.
9
-
10
- ## Results
11
-
12
- | Benchmark | NYNY (req/s) | Sinatra (req/s) |
13
- |-----------|:---------------:|:---------------:|
14
- | Simple |__5012__ |2534 |
15
- | UrlPattern|__4564__ |2338 |
16
- | Filters |__4510__ |2465 |
17
- | Helpers |__4737__ |2663 |
18
-
19
- See below the code for each benchmark
20
-
21
- ## Code
22
- ### Simple
23
- ```ruby
24
- class App < NYNY::App #(or Sinatra::Base)
25
- get '/' do
26
- 'Hello World!'
27
- end
28
- end
5
+ Test: empty
29
6
  ```
30
-
31
- ### UrlPattern
32
- ```ruby
33
- class App < NYNY::App #(or Sinatra::Base)
34
- get '/hello/:name' do
35
- "Hello #{params[:name]}!"
36
- end
37
- end
7
+ user system total real
8
+ nyny: 0.060000 0.010000 0.070000 ( 0.063841)
9
+ sinatra: 0.380000 0.000000 0.380000 ( 0.392611)
38
10
  ```
11
+ NYNY is **6.15x** faster than Sinatra in this test
39
12
 
40
- ### Filters
41
- ```ruby
42
- class App < NYNY::App #(or Sinatra::Base)
43
- before do
44
- request
45
- end
46
-
47
- after do
48
- response
49
- end
50
-
51
- get '/' do
52
- 'Hello World!'
53
- end
54
- end
13
+ Test: hello world
55
14
  ```
15
+ user system total real
16
+ nyny: 0.100000 0.000000 0.100000 ( 0.099356)
17
+ sinatra: 0.250000 0.010000 0.260000 ( 0.253724)
18
+ ```
19
+ NYNY is **2.55x** faster than Sinatra in this test
56
20
 
57
- ### Helpers
58
- ```ruby
59
- module Dude
60
- def da_request_man
61
- request
62
- end
63
- end
21
+ Test: filters
22
+ ```
23
+ user system total real
24
+ nyny: 0.090000 0.000000 0.090000 ( 0.097938)
25
+ sinatra: 0.260000 0.000000 0.260000 ( 0.259718)
26
+ ```
27
+ NYNY is **2.65x** faster than Sinatra in this test
64
28
 
65
- class App < NYNY::App #(or Sinatra::Base)
66
- helpers Dude
29
+ Test: helpers
30
+ ```
31
+ user system total real
32
+ nyny: 0.090000 0.000000 0.090000 ( 0.090412)
33
+ sinatra: 0.240000 0.010000 0.250000 ( 0.239332)
34
+ ```
35
+ NYNY is **2.65x** faster than Sinatra in this test
67
36
 
68
- get '/' do
69
- da_request_man
70
- 'Hello World!'
71
- end
72
- end
37
+ Test: Url patterns
38
+ ```
39
+ user system total real
40
+ nyny: 0.100000 0.000000 0.100000 ( 0.104926)
41
+ sinatra: 0.260000 0.000000 0.260000 ( 0.268531)
73
42
  ```
43
+ NYNY is **2.56x** faster than Sinatra in this test
44
+
data/README.md CHANGED
@@ -33,6 +33,7 @@ Open the browser at [http://localhost:9292](http://localhost:9292)
33
33
  - [Philosophy](#philosophy)
34
34
  - [Why use NYNY instead of Sinatra](#why-use-nyny-instead-of-sinatra)
35
35
  - [Usage](#usage)
36
+ - [Environment](#environment)
36
37
  - [Running](#running)
37
38
  - [Defining routes](#defining-routes)
38
39
  - [Request scope](#request-scope)
@@ -79,24 +80,55 @@ A NYNY app must _always_ be in a class which inherits from `NYNY::App`:
79
80
  end
80
81
  end
81
82
 
83
+ ## Environment
84
+ To get the directory in which your app is running use `NYNY.root`
85
+
86
+ ```ruby
87
+ #/some/folder/server.rb
88
+ require 'nyny'
89
+ puts NYNY.root #=> /some/folder/
90
+ ```
91
+
92
+ To get NYNY's environment, use `NYNY.env`
93
+
94
+ ```ruby
95
+ #env.rb
96
+ require 'nyny'
97
+ puts NYNY.env
98
+ puts NYNY.env.production?
99
+ ```
100
+
101
+ ```bash
102
+ $ ruby env.rb
103
+ development
104
+ false
105
+
106
+ $ ruby env.rb RACK_ENV=production
107
+ production
108
+ true
109
+ ```
110
+
82
111
  ## Running
83
112
  There are two ways to run a NYNY app __directly__ [[?]](#middleware):
84
113
 
85
114
  - by requiring it in a `config.ru` file, and then passing it as argument to the
86
115
  Rack's `run` function:
87
116
 
88
- # config.ru
89
-
90
- require 'app'
91
- run App.new
117
+ ```ruby
118
+ # config.ru
92
119
 
120
+ require 'app'
121
+ run App.new
122
+ ```
93
123
  - by using the `run!` method directly on the app class:
94
124
 
95
- # app.rb
96
-
97
- # ...app class definition...
125
+ ```ruby
126
+ # app.rb
127
+
128
+ # ...app class definition...
98
129
 
99
- App.run!
130
+ App.run!
131
+ ```
100
132
 
101
133
  `run!` takes the port number as optional argument (the default port is 9292).
102
134
  Also the `run!` method will include 2 default middlewares to make the
@@ -110,28 +142,34 @@ in the case a error occurs during a request.
110
142
  NYNY supports the following verbs for defining a route: delete, get, head,
111
143
  options, patch, post, put and trace.
112
144
 
113
- class App < NYNY::App
114
- post '/' do
115
- 'You Posted, dude!'
116
- end
117
- end
145
+ ```ruby
146
+ class App < NYNY::App
147
+ post '/' do
148
+ 'You Posted, dude!'
149
+ end
150
+ end
151
+ ```
118
152
 
119
153
  NYNY also suports basic URL patterns:
120
154
 
121
- class App < NYNY::App
122
- get '/greet/:first_name/:last_name' do
123
- # the last expression in the block is _always_ considered the response body.
124
- "Hello #{params[:first_name]} #{params[:last_name]}!"
125
- end
126
- end
155
+ ```ruby
156
+ class App < NYNY::App
157
+ get '/greet/:first_name/:last_name' do
158
+ # the last expression in the block is _always_ considered the response body.
159
+ "Hello #{params[:first_name]} #{params[:last_name]}!"
160
+ end
161
+ end
162
+ ```
127
163
 
128
164
  you can also tell NYNY to match a regex for a path:
129
165
 
130
- class App < NYNY::App
131
- get /html/ do
132
- 'Your URL contains html!'
133
- end
134
- end
166
+ ```ruby
167
+ class App < NYNY::App
168
+ get /html/ do
169
+ 'Your URL contains html!'
170
+ end
171
+ end
172
+ ```
135
173
 
136
174
  Each block that is passed to a route definition is evaluated in the context of
137
175
  a request scope. See below what methods are available there.
@@ -164,38 +202,44 @@ This means that you can't declare a filter to execute depending on a URL pattern
164
202
  However, you can obtain the same effect by calling next in a before block
165
203
  if the request.path matches a pattern.
166
204
 
167
- class App < NYNY::App
168
- before do
169
- next unless /html/ =~ request.path
170
- headers 'Content-Type' => 'text/html'
171
- end
205
+ ```ruby
206
+ class App < NYNY::App
207
+ before do
208
+ next unless /html/ =~ request.path
209
+ headers 'Content-Type' => 'text/html'
210
+ end
172
211
 
173
- after do
174
- puts response.inspect
175
- end
212
+ after do
213
+ puts response.inspect
214
+ end
176
215
 
177
- get '/' do
178
- 'hello'
179
- end
180
- end
216
+ get '/' do
217
+ 'hello'
218
+ end
219
+ end
220
+ ```
181
221
 
182
222
  ## Middleware
183
223
 
184
224
  A NYNY app is a Rack middleware, which means that it can be used inside
185
225
  Sinatra, Rails, or any other Rack-based app:
186
226
 
187
- class MyApp < Sinatra::Base
188
- use MyNYNYApp
189
- end
227
+ ```ruby
228
+ class MyApp < Sinatra::Base
229
+ use MyNYNYApp
230
+ end
231
+ ```
190
232
 
191
233
  NYNY also supports middleware itself, and that means you can use Rack middleware
192
234
  (or a Sinatra app) inside a NYNY app:
193
235
 
194
- class App < NYNY::App
195
- # this will serve all the files in the "public" folder
196
- use Rack::Static :url => ['public']
197
- use SinatraApp
198
- end
236
+ ```ruby
237
+ class App < NYNY::App
238
+ # this will serve all the files in the "public" folder
239
+ use Rack::Static :url => ['public']
240
+ use SinatraApp
241
+ end
242
+ ```
199
243
 
200
244
  I recommend looking at [the list of Rack middlewares][rack-middleware]
201
245
 
@@ -203,9 +247,17 @@ I recommend looking at [the list of Rack middlewares][rack-middleware]
203
247
 
204
248
  NYNY supports helpers as Sinatra does:
205
249
 
206
- class App < NYNY::App
207
- helpers MyHelperModule
250
+ ```ruby
251
+ class App < NYNY::App
252
+ helpers MyHelperModule
253
+ helpers do
254
+ def using_a_block_to_define_helper
255
+ true
208
256
  end
257
+ end
258
+ end
259
+ ```
260
+
209
261
 
210
262
  Using a helper implies that the helper module is included in the [RequestScope][2],
211
263
  and that all the methods in that module will be available inside a route
@@ -217,44 +269,46 @@ Since version 2.0.0, NYNY added support for extensions.
217
269
  This makes possible to include helpers, middlewares and custom app class
218
270
  methods inside a single module:
219
271
 
220
- module MyKewlExtension
221
- class Middleware
222
- def initialize app
223
- @app = app
224
- end
272
+ ```ruby
273
+ module MyKewlExtension
274
+ class Middleware
275
+ def initialize app
276
+ @app = app
277
+ end
225
278
 
226
- def call env
227
- env['KEWL'] = true
228
- @app.call(env) if @app
229
- end
230
- end
279
+ def call env
280
+ env['KEWL'] = true
281
+ @app.call(env) if @app
282
+ end
283
+ end
231
284
 
232
- module Helpers
233
- def the_ultimate_answer
234
- 42
235
- end
236
- end
285
+ module Helpers
286
+ def the_ultimate_answer
287
+ 42
288
+ end
289
+ end
237
290
 
238
- def get_or_post route, &block
239
- get route, &block
240
- post route, &block
241
- end
291
+ def get_or_post route, &block
292
+ get route, &block
293
+ post route, &block
294
+ end
242
295
 
243
- def self.registered app
244
- app.use Middleware
245
- app.helpers Helpers
296
+ def self.registered app
297
+ app.use Middleware
298
+ app.helpers Helpers
246
299
 
247
- app.get_or_post '/' do
248
- "After many years of hard computation, the answer is #{the_ultimate_answer}"
249
- end
250
- end
300
+ app.get_or_post '/' do
301
+ "After many years of hard computation, the answer is #{the_ultimate_answer}"
251
302
  end
303
+ end
304
+ end
252
305
 
253
- class App < NYNY::App
254
- register MyKewlExtension
255
- end
306
+ class App < NYNY::App
307
+ register MyKewlExtension
308
+ end
256
309
 
257
- App.run!
310
+ App.run!
311
+ ```
258
312
 
259
313
  By default, the App class will `extend` the provided extension module.
260
314
  Optionally, an extension can add a `registered` method, which will be invoked
@@ -0,0 +1,95 @@
1
+ #!ruby -I ./lib -I lib
2
+ require 'nyny'
3
+ require 'ruby-prof'
4
+ require 'benchmark'
5
+ require 'sinatra'
6
+ include Benchmark
7
+
8
+ set :run, false #do not run sinatra's builtin web server
9
+
10
+ def build_apps &block
11
+ sinatra = Class.new(Sinatra::Base, &block).new
12
+ nyny = Class.new(NYNY::App, &block).new
13
+ return [nyny, sinatra].map {|app| Rack::MockRequest.new(app) }
14
+ end
15
+
16
+ def run_test name, apps, &block
17
+ nyny, sinatra = apps
18
+ prc = Proc.new(&block)
19
+
20
+ puts "\nTest: #{name}"
21
+ Benchmark.benchmark(CAPTION, 7, FORMAT, "> NYNY/Sinatra:") do |x|
22
+ nyny_time = x.report("nyny: ") { 1000.times { prc.call(nyny) } }
23
+ sinatra_time = x.report("sinatra:") { 1000.times { prc.call(sinatra) } }
24
+ puts "NYNY is #{"%.2f" % [sinatra_time.real/nyny_time.real]}x faster than Sinatra in this test"
25
+ end
26
+ end
27
+
28
+ puts "Comparing NYNY #{NYNY::VERSION} with Sinatra #{Sinatra::VERSION}"
29
+
30
+ #
31
+ # Empty app
32
+ apps = build_apps do
33
+ #empty app
34
+ end
35
+ run_test 'empty', apps do |app|
36
+ app.get '/'
37
+ end
38
+
39
+ #
40
+ # Hello World
41
+ apps = build_apps do
42
+ get '/' do
43
+ 'Hello World'
44
+ end
45
+ end
46
+ run_test 'hello world', apps do |app|
47
+ app.get '/'
48
+ end
49
+
50
+ #
51
+ # Filters
52
+ apps = build_apps do
53
+ before do
54
+ request
55
+ end
56
+
57
+ after do
58
+ response
59
+ end
60
+
61
+ get '/' do
62
+ 'Hello World!'
63
+ end
64
+ end
65
+ run_test 'filters', apps do |app|
66
+ app.get '/'
67
+ end
68
+
69
+ #
70
+ # Helpers
71
+ apps = build_apps do
72
+ helpers do
73
+ def da_request
74
+ request
75
+ end
76
+ end
77
+
78
+ get '/' do
79
+ da_request
80
+ end
81
+ end
82
+ run_test 'helpers', apps do |app|
83
+ app.get '/'
84
+ end
85
+
86
+ #
87
+ # Url patterns
88
+ apps = build_apps do
89
+ get '/:name' do
90
+ params[:name]
91
+ end
92
+ end
93
+ run_test 'Url patterns', apps do |app|
94
+ app.get '/foo'
95
+ end