roda 3.39.0 → 3.40.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f01105e24f4eae80a69f5734f93d3dfe54b5f6be2489521f1d886053c569102
4
- data.tar.gz: 2aebf30460c7d5352ee15baf3f884e59dac972e0aadd63aa7ab81445a8a29f65
3
+ metadata.gz: 8e87645db18482f3ad97d106e268d76b2567d074490f37d7e99d52d06e4e5483
4
+ data.tar.gz: b84b082c2f27fcbd31254cb80de5e6610b7417e722eaf3dc3d8753a4604a0701
5
5
  SHA512:
6
- metadata.gz: d3fd374b3d700106ca814fff8f2dd0c66a3295955f27a453ef5d9fb2ba7fdea583d76ce82f91efb8e2ebcbb97a07e664f3f008689d51eb67ae39aebdd86a5d0e
7
- data.tar.gz: 59c34c88ab1e5a5bc5017d46707a530c7cd002f4262c30751ba6429983b32477b813d83ada45a19873be711d1d2bd0abd95fe2a5c44c01038ad4a32dbb8f276d
6
+ metadata.gz: 3b21d6fa4b33c029a8b23a8ec437e70e2799e3f2bec27239d3cbfc5a1a4bb8cd82fc95309ad27d22243695298535b02687b0948218df1f7a1a0812242079e3b7
7
+ data.tar.gz: 3dc9629b16a4d9f496cee61bc40396f6893bfe114666ba7554327cd052946719410e2f4e89a27388cea291fd7b5ba1bcd37c669aa1dfc7b64c48a6622bafb013
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ = 3.40.0 (2021-01-14)
2
+
3
+ * Add freeze_template_caches! to the precompile_templates plugin, which ensures all templates are precompiled, and speeds up template access (jeremyevans)
4
+
5
+ * Add precompile_views to the precompile_templates plugin, which precompiles the optimized render methods (jeremyevans)
6
+
7
+ * Have RodaCache#freeze return the frozen internal hash (which no longer needs a mutex for thread-safety) (jeremyevans)
8
+
9
+ * Speed up the view method in the render plugin even more when freezing the application (jeremyevans)
10
+
11
+ * Speed up the view method in the render plugin when called with a single argument (jeremyevans)
12
+
1
13
  = 3.39.0 (2020-12-15)
2
14
 
3
15
  * Speed up relative_path plugin if relative_path or relative_prefix is called more than once (jeremyevans)
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2020 Jeremy Evans
1
+ Copyright (c) 2014-2021 Jeremy Evans
2
2
  Copyright (c) 2010-2014 Michel Martens, Damian Janowski and Cyril David
3
3
  Copyright (c) 2008-2009 Christian Neukirchen
4
4
 
@@ -0,0 +1,24 @@
1
+ = New Features
2
+
3
+ * A precompile_views method has been added to the
4
+ precompile_templates plugin. This method works with Roda's
5
+ optimized compiled view methods, allowing additional memory
6
+ sharing between parent and child processes.
7
+
8
+ * A freeze_template_caches! method has been added to the
9
+ precompile_templates plugin. This freezes the template caches,
10
+ preventing the compilation of additional templates, useful for
11
+ enforcing that only precompiled templates are used. Additionally,
12
+ this speeds up access to the template caches.
13
+
14
+ * RodaCache#freeze now returns the frozen internal hash, which can
15
+ then be accessed without a mutex. Previously, freeze only froze
16
+ the receiver and not the internal hash, so it didn't have the
17
+ expected effect.
18
+
19
+ = Other Improvements
20
+
21
+ * The view method in the render plugin is now faster in most cases
22
+ when a single argument is used. When freezing the application,
23
+ an additional optimization is performed to increase the
24
+ performance of the view method even further.
@@ -22,6 +22,13 @@ class Roda
22
22
  @mutex.synchronize{@hash[key] = value}
23
23
  end
24
24
 
25
+ # Return the frozen internal hash. The internal hash can then
26
+ # be accessed directly since it is frozen and there are no
27
+ # thread safety issues.
28
+ def freeze
29
+ @hash.freeze
30
+ end
31
+
25
32
  private
26
33
 
27
34
  # Create a copy of the cache with a separate mutex.
@@ -13,32 +13,33 @@ class Roda
13
13
  # all of the child processes can use the same precompiled templates, which
14
14
  # saves memory.
15
15
  #
16
- # After loading the plugin, you can call +precompile_templates+ with
17
- # the pattern of templates you would like to precompile:
16
+ # Another advantage of the precompile_templates plugin is that after
17
+ # template precompilation, access to the template file in the file system is
18
+ # no longer needed, so this can be used with security features that do not
19
+ # allow access to the template files at runtime.
20
+ #
21
+ # After loading the plugin, you should call precompile_views with an array
22
+ # of views to compile, using the same argument you are passing to view or
23
+ # render:
18
24
  #
19
25
  # plugin :precompile_templates
20
- # precompile_templates "views/\*\*/*.erb"
26
+ # precompile_views %w'view1 view2'
27
+ #
28
+ # If the view requires local variables, you should call precompile_views with a second
29
+ # argument for the local variables:
21
30
  #
22
- # That will precompile all erb template files in the views directory or
23
- # any subdirectory.
31
+ # plugin :precompile_templates
32
+ # precompile_views :view3, [:local_var1, :local_var2]
24
33
  #
25
- # If the templates use local variables, you need to specify which local
26
- # variables to precompile, which should be an array of symbols:
34
+ # After all templates are precompiled, you can optionally use freeze_template_caches!,
35
+ # which will freeze the template caches so that any template compilation at runtime
36
+ # will result in an error. This also speeds up template cache access, since the
37
+ # template caches no longer need a mutex.
27
38
  #
28
- # precompile_templates 'views/users/_*.erb', locals: [:user]
39
+ # freeze_template_caches!
29
40
  #
30
41
  # Note that you should use Tilt 2.0.1+ if you are using this plugin, so
31
42
  # that locals are handled in the same order.
32
- #
33
- # You can specify other render options when calling +precompile_templates+,
34
- # including +:cache_key+, +:template_class+, and +:template_opts+. If you
35
- # are passing any of those options to render/view for the template, you
36
- # should pass the same options when precompiling the template.
37
- #
38
- # To compile inline templates, just pass a single hash containing an :inline
39
- # to +precompile_templates+:
40
- #
41
- # precompile_templates inline: some_template_string
42
43
  module PrecompileTemplates
43
44
  # Load the render plugin as precompile_templates depends on it.
44
45
  def self.load_dependencies(app, opts=OPTS)
@@ -46,8 +47,49 @@ class Roda
46
47
  end
47
48
 
48
49
  module ClassMethods
49
- # Precompile the templates using the given options. See PrecompileTemplates
50
- # for details.
50
+ # Freeze the template caches. Should be called after precompiling all templates during
51
+ # application startup, if you don't want to allow templates to be cached at runtime.
52
+ # In addition to ensuring that no templates are compiled at runtime, this also speeds
53
+ # up rendering by freezing the template caches, so that a mutex is not needed to access
54
+ # them.
55
+ def freeze_template_caches!
56
+ _freeze_layout_method
57
+
58
+ opts[:render] = render_opts.merge(
59
+ :cache=>render_opts[:cache].freeze,
60
+ :template_method_cache=>render_opts[:template_method_cache].freeze,
61
+ ).freeze
62
+ self::RodaCompiledTemplates.freeze
63
+
64
+ nil
65
+ end
66
+
67
+ # Precompile the templates using the given options. Note that this doesn't
68
+ # handle optimized template methods supported in newer versions of Roda, but
69
+ # there are still cases where makes sense to use it.
70
+ #
71
+ # You can call +precompile_templates+ with the pattern of templates you would
72
+ # like to precompile:
73
+ #
74
+ # precompile_templates "views/**/*.erb"
75
+ #
76
+ # That will precompile all erb template files in the views directory or
77
+ # any subdirectory.
78
+ #
79
+ # If the templates use local variables, you need to specify which local
80
+ # variables to precompile, which should be an array of symbols:
81
+ #
82
+ # precompile_templates 'views/users/_*.erb', locals: [:user]
83
+ #
84
+ # You can specify other render options when calling +precompile_templates+,
85
+ # including +:cache_key+, +:template_class+, and +:template_opts+. If you
86
+ # are passing any of those options to render/view for the template, you
87
+ # should pass the same options when precompiling the template.
88
+ #
89
+ # To compile inline templates, just pass a single hash containing an :inline
90
+ # to +precompile_templates+:
91
+ #
92
+ # precompile_templates inline: some_template_string
51
93
  def precompile_templates(pattern, opts=OPTS)
52
94
  if pattern.is_a?(Hash)
53
95
  opts = pattern.merge(opts)
@@ -68,7 +110,40 @@ class Roda
68
110
  instance = allocate
69
111
  compile_opts.each do |compile_opt|
70
112
  template = instance.send(:retrieve_template, compile_opt)
71
- Render.tilt_template_compiled_method(template, locals, self)
113
+ begin
114
+ Render.tilt_template_compiled_method(template, locals, self)
115
+ rescue NotImplementedError
116
+ # When freezing template caches, you may want to precompile a template for a
117
+ # template type that doesn't support template precompilation, just to populate
118
+ # the cache. Tilt rescues NotImplementedError in this case, which we can ignore.
119
+ nil
120
+ end
121
+ end
122
+
123
+ nil
124
+ end
125
+
126
+ # Precompile the given views with the given locals, handling optimized template methods.
127
+ def precompile_views(views, locals=EMPTY_ARRAY)
128
+ instance = allocate
129
+ views = Array(views)
130
+
131
+ if locals.empty?
132
+ opts = OPTS
133
+ else
134
+ locals_hash = {}
135
+ locals.each{|k| locals_hash[k] = nil}
136
+ opts = {:locals=>locals_hash}
137
+ end
138
+
139
+ views.each do |view|
140
+ instance.send(:retrieve_template, instance.send(:render_template_opts, view, opts))
141
+ end
142
+
143
+ if locals_hash
144
+ views.each do |view|
145
+ instance.send(:_optimized_render_method_for_locals, view, locals_hash)
146
+ end
72
147
  end
73
148
 
74
149
  nil
@@ -333,6 +333,25 @@ class Roda
333
333
  end
334
334
 
335
335
  module ClassMethods
336
+ # :nocov:
337
+ if COMPILED_METHOD_SUPPORT
338
+ # :nocov:
339
+ # If using compiled methods and there is an optimized layout, speed up
340
+ # access to the layout method to improve the performance of view.
341
+ def freeze
342
+ begin
343
+ _freeze_layout_method
344
+ rescue
345
+ # This is only for optimization, if any errors occur, they can be ignored.
346
+ # One possibility for error is the app doesn't use a layout, but doesn't
347
+ # specifically set the :layout=>false plugin option.
348
+ nil
349
+ end
350
+
351
+ super
352
+ end
353
+ end
354
+
336
355
  # Copy the rendering options into the subclass, duping
337
356
  # them as necessary to prevent changes in the subclass
338
357
  # affecting the parent class.
@@ -352,6 +371,27 @@ class Roda
352
371
  def render_opts
353
372
  opts[:render]
354
373
  end
374
+
375
+ private
376
+
377
+ # Precompile the layout method, to reduce method calls to look it up at runtime.
378
+ def _freeze_layout_method
379
+ if render_opts[:layout]
380
+ instance = allocate
381
+ instance.send(:retrieve_template, instance.send(:view_layout_opts, OPTS))
382
+
383
+ # :nocov:
384
+ if COMPILED_METHOD_SUPPORT
385
+ # :nocov:
386
+ if (layout_template = render_opts[:optimize_layout]) && !opts[:render][:optimized_layout_method_created]
387
+ instance.send(:retrieve_template, :template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
388
+ layout_method = opts[:render][:template_method_cache][:_roda_layout]
389
+ define_method(:_layout_method){layout_method}
390
+ opts[:render] = opts[:render].merge(:optimized_layout_method_created=>true)
391
+ end
392
+ end
393
+ end
394
+ end
355
395
  end
356
396
 
357
397
  module InstanceMethods
@@ -379,15 +419,19 @@ class Roda
379
419
  if optimized_template
380
420
  content = send(optimized_template, OPTS)
381
421
 
382
- render_opts = self.class.opts[:render]
383
- if layout_template = render_opts[:optimize_layout]
384
- method_cache = render_opts[:template_method_cache]
385
- unless layout_method = method_cache[:_roda_layout]
386
- retrieve_template(:template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
387
- layout_method = method_cache[:_roda_layout]
388
- end
422
+ # First, check if the optimized layout method has already been created,
423
+ # and use it if so. This way avoids the extra conditional and local variable
424
+ # assignments in the next section.
425
+ if layout_method = _layout_method
426
+ return send(layout_method, OPTS){content}
427
+ end
389
428
 
390
- if layout_method
429
+ # If we have an optimized template method but no optimized layout method, create the
430
+ # optimized layout method if possible and use it. If you can't create the optimized
431
+ # layout method, fall through to the slower approach.
432
+ if layout_template = self.class.opts[:render][:optimize_layout]
433
+ retrieve_template(:template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
434
+ if layout_method = _layout_method
391
435
  return send(layout_method, OPTS){content}
392
436
  end
393
437
  end
@@ -428,6 +472,11 @@ class Roda
428
472
  method_cache[template]
429
473
  end
430
474
 
475
+ # Return a symbol containing the optimized layout method
476
+ def _layout_method
477
+ self.class.opts[:render][:template_method_cache][:_roda_layout]
478
+ end
479
+
431
480
  # Use an optimized render path for templates with a hash of locals. Returns the result
432
481
  # of the template render if the optimized path is used, or nil if the optimized
433
482
  # path is not used and the long method needs to be used.
@@ -471,11 +520,15 @@ class Roda
471
520
  end
472
521
  else
473
522
  # :nocov:
474
- def _cached_template_method(template)
523
+ def _cached_template_method(_)
475
524
  nil
476
525
  end
477
526
 
478
- def _cached_template_method_key(template)
527
+ def _cached_template_method_key(_)
528
+ nil
529
+ end
530
+
531
+ def _layout_method
479
532
  nil
480
533
  end
481
534
 
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 39
7
+ RodaMinorVersion = 40
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.39.0
4
+ version: 3.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-15 00:00:00.000000000 Z
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -174,16 +174,8 @@ extra_rdoc_files:
174
174
  - MIT-LICENSE
175
175
  - CHANGELOG
176
176
  - doc/conventions.rdoc
177
- - doc/release_notes/3.7.0.txt
178
177
  - doc/release_notes/3.0.0.txt
179
178
  - doc/release_notes/3.1.0.txt
180
- - doc/release_notes/3.2.0.txt
181
- - doc/release_notes/3.3.0.txt
182
- - doc/release_notes/3.4.0.txt
183
- - doc/release_notes/3.5.0.txt
184
- - doc/release_notes/3.6.0.txt
185
- - doc/release_notes/3.8.0.txt
186
- - doc/release_notes/3.9.0.txt
187
179
  - doc/release_notes/3.10.0.txt
188
180
  - doc/release_notes/3.11.0.txt
189
181
  - doc/release_notes/3.12.0.txt
@@ -195,6 +187,7 @@ extra_rdoc_files:
195
187
  - doc/release_notes/3.17.0.txt
196
188
  - doc/release_notes/3.18.0.txt
197
189
  - doc/release_notes/3.19.0.txt
190
+ - doc/release_notes/3.2.0.txt
198
191
  - doc/release_notes/3.20.0.txt
199
192
  - doc/release_notes/3.21.0.txt
200
193
  - doc/release_notes/3.22.0.txt
@@ -205,6 +198,7 @@ extra_rdoc_files:
205
198
  - doc/release_notes/3.27.0.txt
206
199
  - doc/release_notes/3.28.0.txt
207
200
  - doc/release_notes/3.29.0.txt
201
+ - doc/release_notes/3.3.0.txt
208
202
  - doc/release_notes/3.30.0.txt
209
203
  - doc/release_notes/3.31.0.txt
210
204
  - doc/release_notes/3.32.0.txt
@@ -215,6 +209,13 @@ extra_rdoc_files:
215
209
  - doc/release_notes/3.37.0.txt
216
210
  - doc/release_notes/3.38.0.txt
217
211
  - doc/release_notes/3.39.0.txt
212
+ - doc/release_notes/3.4.0.txt
213
+ - doc/release_notes/3.40.0.txt
214
+ - doc/release_notes/3.5.0.txt
215
+ - doc/release_notes/3.6.0.txt
216
+ - doc/release_notes/3.7.0.txt
217
+ - doc/release_notes/3.8.0.txt
218
+ - doc/release_notes/3.9.0.txt
218
219
  files:
219
220
  - CHANGELOG
220
221
  - MIT-LICENSE
@@ -256,6 +257,7 @@ files:
256
257
  - doc/release_notes/3.38.0.txt
257
258
  - doc/release_notes/3.39.0.txt
258
259
  - doc/release_notes/3.4.0.txt
260
+ - doc/release_notes/3.40.0.txt
259
261
  - doc/release_notes/3.5.0.txt
260
262
  - doc/release_notes/3.6.0.txt
261
263
  - doc/release_notes/3.7.0.txt
@@ -394,7 +396,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
394
396
  - !ruby/object:Gem::Version
395
397
  version: '0'
396
398
  requirements: []
397
- rubygems_version: 3.1.4
399
+ rubygems_version: 3.2.3
398
400
  signing_key:
399
401
  specification_version: 4
400
402
  summary: Routing tree web toolkit