roda 3.39.0 → 3.40.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/CHANGELOG +12 -0
- data/MIT-LICENSE +1 -1
- data/doc/release_notes/3.40.0.txt +24 -0
- data/lib/roda/cache.rb +7 -0
- data/lib/roda/plugins/precompile_templates.rb +96 -21
- data/lib/roda/plugins/render.rb +63 -10
- data/lib/roda/version.rb +1 -1
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e87645db18482f3ad97d106e268d76b2567d074490f37d7e99d52d06e4e5483
|
4
|
+
data.tar.gz: b84b082c2f27fcbd31254cb80de5e6610b7417e722eaf3dc3d8753a4604a0701
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/MIT-LICENSE
CHANGED
@@ -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.
|
data/lib/roda/cache.rb
CHANGED
@@ -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
|
-
#
|
17
|
-
# the
|
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
|
-
#
|
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
|
-
#
|
23
|
-
#
|
31
|
+
# plugin :precompile_templates
|
32
|
+
# precompile_views :view3, [:local_var1, :local_var2]
|
24
33
|
#
|
25
|
-
#
|
26
|
-
#
|
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
|
-
#
|
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
|
-
#
|
50
|
-
#
|
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
|
-
|
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
|
data/lib/roda/plugins/render.rb
CHANGED
@@ -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
|
-
|
383
|
-
if
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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
|
-
|
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(
|
523
|
+
def _cached_template_method(_)
|
475
524
|
nil
|
476
525
|
end
|
477
526
|
|
478
|
-
def _cached_template_method_key(
|
527
|
+
def _cached_template_method_key(_)
|
528
|
+
nil
|
529
|
+
end
|
530
|
+
|
531
|
+
def _layout_method
|
479
532
|
nil
|
480
533
|
end
|
481
534
|
|
data/lib/roda/version.rb
CHANGED
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.
|
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:
|
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.
|
399
|
+
rubygems_version: 3.2.3
|
398
400
|
signing_key:
|
399
401
|
specification_version: 4
|
400
402
|
summary: Routing tree web toolkit
|