nitro 0.27.0 → 0.28.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.
- data/CHANGELOG +276 -0
- data/ProjectInfo +4 -4
- data/README +9 -1
- data/Rakefile +1 -1
- data/doc/AUTHORS +30 -17
- data/doc/RELEASES +110 -23
- data/lib/glue/sweeper.rb +1 -1
- data/lib/glue/webfile.rb +1 -1
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/acgi.rb +5 -1
- data/lib/nitro/adapter/cgi.rb +4 -0
- data/lib/nitro/adapter/fastcgi.rb +12 -1
- data/lib/nitro/adapter/mongrel.rb +219 -0
- data/lib/nitro/adapter/scgi.rb +62 -69
- data/lib/nitro/caching.rb +6 -5
- data/lib/nitro/caching/actions.rb +14 -8
- data/lib/nitro/caching/fragments.rb +32 -17
- data/lib/nitro/caching/output.rb +10 -2
- data/lib/nitro/cgi.rb +7 -3
- data/lib/nitro/cgi/stream.rb +1 -3
- data/lib/nitro/compiler.rb +5 -4
- data/lib/nitro/compiler/errors.rb +1 -1
- data/lib/nitro/compiler/morphing.rb +2 -2
- data/lib/nitro/compiler/script.rb +1 -1
- data/lib/nitro/context.rb +8 -2
- data/lib/nitro/controller.rb +1 -1
- data/lib/nitro/dispatcher.rb +0 -2
- data/lib/nitro/element.rb +5 -5
- data/lib/nitro/flash.rb +1 -1
- data/lib/nitro/helper.rb +2 -2
- data/lib/nitro/helper/form.rb +1 -1
- data/lib/nitro/helper/form/controls.rb +2 -1
- data/lib/nitro/helper/javascript.rb +1 -1
- data/lib/nitro/helper/javascript/morphing.rb +1 -1
- data/lib/nitro/helper/layout.rb +1 -1
- data/lib/nitro/helper/pager.rb +7 -3
- data/lib/nitro/helper/rss.rb +1 -1
- data/lib/nitro/render.rb +1 -1
- data/lib/nitro/scaffolding.rb +26 -4
- data/lib/nitro/server/drb.rb +106 -0
- data/lib/nitro/server/runner.rb +23 -2
- data/lib/nitro/session.rb +33 -16
- data/lib/nitro/session/drb.rb +6 -20
- data/lib/nitro/session/file.rb +4 -49
- data/lib/nitro/session/memory.rb +16 -0
- data/lib/nitro/session/og.rb +4 -46
- data/src/part/admin/controller.rb +2 -3
- data/src/part/admin/template/index.xhtml +1 -1
- data/test/nitro/tc_cgi.rb +72 -3
- data/test/nitro/tc_render.rb +1 -1
- data/test/nitro/tc_session.rb +16 -15
- metadata +12 -14
- data/lib/nitro/caching/invalidation.rb +0 -25
- data/lib/nitro/caching/stores.rb +0 -94
- data/lib/nitro/helper/form/test.xhtml +0 -0
- data/lib/nitro/session/drbserver.rb +0 -84
data/lib/nitro/caching.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'fileutils'
|
|
2
|
-
|
|
3
1
|
require 'glue/attribute'
|
|
4
2
|
require 'glue/configuration'
|
|
5
3
|
require 'glue/sweeper'
|
|
@@ -10,7 +8,11 @@ require 'nitro/caching/fragments'
|
|
|
10
8
|
|
|
11
9
|
module Nitro
|
|
12
10
|
|
|
13
|
-
#
|
|
11
|
+
# Nitro Hierarchical Caching system.
|
|
12
|
+
#
|
|
13
|
+
# # Output caching (caches the whole page, main action)
|
|
14
|
+
# # Action caching (cache the fragment generated by an action)
|
|
15
|
+
# # Fragment caching (fine-grained fragment caching, cache snippets of code)
|
|
14
16
|
#--
|
|
15
17
|
# TODO: add per controller caching_enabled.
|
|
16
18
|
#++
|
|
@@ -21,8 +23,7 @@ module Caching
|
|
|
21
23
|
|
|
22
24
|
setting :caching_enabled, :default => true, :doc => 'Globaly enable/disable caching'
|
|
23
25
|
|
|
24
|
-
def self.
|
|
25
|
-
super
|
|
26
|
+
def self.included(base) #:nodoc:
|
|
26
27
|
base.send :include, Output, Actions, Fragments
|
|
27
28
|
base.module_eval do
|
|
28
29
|
# @caching_enabled = true
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
2
|
|
|
3
|
+
require 'nitro/caching/fragments'
|
|
4
|
+
|
|
3
5
|
module Nitro
|
|
4
6
|
|
|
5
7
|
# Adds support for caching.
|
|
6
8
|
|
|
7
9
|
module Caching
|
|
8
10
|
|
|
9
|
-
# Action caching
|
|
11
|
+
# Action caching is a set of helper to allow the caching
|
|
12
|
+
# generated by an action. In the caching hierarchy it lies
|
|
13
|
+
# between Output caching (top action, full page) and fragment
|
|
14
|
+
# caching (fine-grained caching).
|
|
10
15
|
|
|
11
16
|
module Actions
|
|
12
17
|
|
|
13
|
-
def self.
|
|
14
|
-
super
|
|
18
|
+
def self.included(base) # :nodoc:
|
|
15
19
|
base.extend(ClassMethods)
|
|
16
20
|
end
|
|
17
21
|
|
|
@@ -20,10 +24,10 @@ module Caching
|
|
|
20
24
|
def cache_action(*actions)
|
|
21
25
|
return unless caching_enabled?
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
before(
|
|
24
28
|
%{
|
|
25
29
|
fragment_name = "\#\{@action_name\}\#{@request.query_string}"
|
|
26
|
-
if fragment =
|
|
30
|
+
if fragment = Fragments.get(fragment_name)
|
|
27
31
|
@out = fragment
|
|
28
32
|
return
|
|
29
33
|
end
|
|
@@ -31,10 +35,10 @@ module Caching
|
|
|
31
35
|
:only => actions
|
|
32
36
|
)
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
after(
|
|
35
39
|
%{
|
|
36
40
|
fragment_name = "\#\{@action_name\}\#{@request.query_string}"
|
|
37
|
-
|
|
41
|
+
Fragments.put(fragment_name, @out)
|
|
38
42
|
},
|
|
39
43
|
:only => actions
|
|
40
44
|
)
|
|
@@ -44,8 +48,10 @@ module Caching
|
|
|
44
48
|
|
|
45
49
|
private
|
|
46
50
|
|
|
51
|
+
# Expire the cached fragment of the given actions.
|
|
52
|
+
#
|
|
47
53
|
#--
|
|
48
|
-
# FIXME: not
|
|
54
|
+
# FIXME: not very good implementation?
|
|
49
55
|
#++
|
|
50
56
|
|
|
51
57
|
def expire_action(*actions)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
2
|
|
|
3
|
+
require 'glue/configuration'
|
|
3
4
|
require 'glue/attribute'
|
|
4
|
-
require '
|
|
5
|
+
require 'glue/cache/memory'
|
|
5
6
|
|
|
6
7
|
module Nitro
|
|
7
8
|
|
|
@@ -10,40 +11,53 @@ module Nitro
|
|
|
10
11
|
module Caching
|
|
11
12
|
|
|
12
13
|
# Action caching. Caches a fragment, ie a page part.
|
|
13
|
-
# Use output
|
|
14
|
+
# Use output caching for full page caching.
|
|
14
15
|
|
|
15
16
|
module Fragments
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def self.store
|
|
20
|
-
@@store
|
|
21
|
-
end
|
|
18
|
+
# The cache used to store the fragments.
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
setting :cache, :default => nil, :doc => 'The cache used to store the fragments'
|
|
21
|
+
|
|
22
|
+
#--
|
|
23
|
+
# gmosx, FIXME: this is a hack, improve setting
|
|
24
|
+
# implementation.
|
|
25
|
+
#++
|
|
26
|
+
|
|
27
|
+
@@cache = Glue::MemoryCache.new
|
|
26
28
|
|
|
27
29
|
def self.get(name, options = {})
|
|
28
|
-
return @@
|
|
30
|
+
return @@cache.get(name, options)
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def self.put(name, content = nil, options = {})
|
|
32
|
-
@@
|
|
34
|
+
@@cache.put(name, content, options)
|
|
33
35
|
return content
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
def self.append_features(base) # :nodoc:
|
|
37
|
-
super
|
|
38
|
-
end
|
|
39
|
-
|
|
40
38
|
private
|
|
41
39
|
|
|
40
|
+
# Helper method to cache a fragment.
|
|
41
|
+
#
|
|
42
|
+
# === Example
|
|
43
|
+
#
|
|
44
|
+
# ...
|
|
45
|
+
# <h1>Article list</h1>
|
|
46
|
+
#
|
|
47
|
+
# <?r cache(:my_cache_key) do ?>
|
|
48
|
+
# <ul>
|
|
49
|
+
# <li each="a in Article.all">#{a.title}</li>
|
|
50
|
+
# </ul>
|
|
51
|
+
# <?r end ?>
|
|
52
|
+
# ...
|
|
53
|
+
|
|
42
54
|
def cache(name = nil, options = {}, &block)
|
|
43
55
|
name = @action_name unless name
|
|
44
56
|
cache_fragment(block, "#{name}#{options}", options)
|
|
45
57
|
end
|
|
46
58
|
|
|
59
|
+
# Internal method, prefer to use cache instead.
|
|
60
|
+
|
|
47
61
|
def cache_fragment(block, name, options = {})
|
|
48
62
|
unless caching_enabled?
|
|
49
63
|
block.call
|
|
@@ -59,13 +73,14 @@ module Caching
|
|
|
59
73
|
end
|
|
60
74
|
end
|
|
61
75
|
|
|
76
|
+
# Expire a cached fragment.
|
|
62
77
|
#--
|
|
63
78
|
# gmosx: If you modify the code here, don't forget to modify
|
|
64
79
|
# the same method on the sweeper.
|
|
65
80
|
#++
|
|
66
81
|
|
|
67
82
|
def expire_fragment(name, options = {})
|
|
68
|
-
Fragments.
|
|
83
|
+
Fragments.cache.delete(name, options)
|
|
69
84
|
end
|
|
70
85
|
end
|
|
71
86
|
|
data/lib/nitro/caching/output.rb
CHANGED
|
@@ -6,12 +6,20 @@ module Nitro
|
|
|
6
6
|
|
|
7
7
|
module Caching
|
|
8
8
|
|
|
9
|
-
# Output caching
|
|
9
|
+
# The Output caching subsystem stores whole pages in the
|
|
10
|
+
# filesystem to be served directly be the front web server
|
|
11
|
+
# (Lighttpd, Apache, etc) for optimal performance.
|
|
12
|
+
#
|
|
13
|
+
# Nitro promotes coding your application in such a way as to
|
|
14
|
+
# allow for output caching to the greatest extend.
|
|
15
|
+
#--
|
|
16
|
+
# gmosx, FIXME: Don't create excessive directories, use better
|
|
17
|
+
# rewrite rules to handle xxx.html files.
|
|
18
|
+
#++
|
|
10
19
|
|
|
11
20
|
module Output
|
|
12
21
|
|
|
13
22
|
def self.included(base) # :nodoc:
|
|
14
|
-
super
|
|
15
23
|
base.extend(ClassMethods)
|
|
16
24
|
base.module_eval do
|
|
17
25
|
cattr_accessor :output_cache_root, 'public'
|
data/lib/nitro/cgi.rb
CHANGED
|
@@ -45,9 +45,13 @@ class Cgi
|
|
|
45
45
|
out.print(Cgi.response_headers(context))
|
|
46
46
|
|
|
47
47
|
if context.out.is_a?(IO)
|
|
48
|
-
|
|
49
|
-
out.
|
|
50
|
-
|
|
48
|
+
begin
|
|
49
|
+
while buf = context.out.read(4096)
|
|
50
|
+
out.write(buf)
|
|
51
|
+
end
|
|
52
|
+
ensure
|
|
53
|
+
context.out.close
|
|
54
|
+
end
|
|
51
55
|
else
|
|
52
56
|
out.print(context.out)
|
|
53
57
|
end
|
data/lib/nitro/cgi/stream.rb
CHANGED
data/lib/nitro/compiler.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'nano/kernel/singleton'
|
|
2
|
-
|
|
3
1
|
require 'glue/template'
|
|
4
2
|
|
|
5
3
|
require 'nitro/compiler/elements'
|
|
@@ -215,14 +213,17 @@ class Compiler
|
|
|
215
213
|
code << "params = [];"
|
|
216
214
|
end
|
|
217
215
|
code << %{
|
|
218
|
-
|
|
219
|
-
context.query_string.split(/[&;]/)
|
|
216
|
+
unless context.query_string.blank?
|
|
217
|
+
all_params = context.query_string.split(/[&;]/)
|
|
218
|
+
is_hash = all_params.first.index('=')
|
|
219
|
+
all_params.each_with_index do |qs, i|
|
|
220
220
|
}
|
|
221
221
|
# Don't pass more parameters than the action's arity.
|
|
222
222
|
if param_count > 0
|
|
223
223
|
code << "break unless i < #{param_count};"
|
|
224
224
|
end
|
|
225
225
|
code << %{
|
|
226
|
+
break if qs.index('=') and not is_hash
|
|
226
227
|
params[i] = CGI.unescape(qs.split(/=/).last)
|
|
227
228
|
end
|
|
228
229
|
end
|
data/lib/nitro/context.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'facet/kernel/assign_with'
|
|
2
2
|
|
|
3
3
|
require 'nitro/cgi'
|
|
4
4
|
require 'nitro/cgi/request'
|
|
@@ -55,7 +55,13 @@ class Context
|
|
|
55
55
|
# end of the HTTP request handling code.
|
|
56
56
|
|
|
57
57
|
def close
|
|
58
|
-
|
|
58
|
+
if @session
|
|
59
|
+
# Ugly hack: need to use AOP instead
|
|
60
|
+
if @session.has_key?(:FLASH)
|
|
61
|
+
@session[:FLASH].clean
|
|
62
|
+
end
|
|
63
|
+
@session.sync
|
|
64
|
+
end
|
|
59
65
|
end
|
|
60
66
|
alias_method :finish, :close
|
|
61
67
|
|
data/lib/nitro/controller.rb
CHANGED
data/lib/nitro/dispatcher.rb
CHANGED
data/lib/nitro/element.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require '
|
|
3
|
-
require '
|
|
4
|
-
require '
|
|
5
|
-
require '
|
|
1
|
+
require 'facet/string/capitalized'
|
|
2
|
+
require 'facet/string/camelize'
|
|
3
|
+
require 'facet/string/underscore'
|
|
4
|
+
require 'facet/dir/self/recurse'
|
|
5
|
+
require 'facet/annotation'
|
|
6
6
|
|
|
7
7
|
require 'glue/flexob'
|
|
8
8
|
require 'glue/configuration'
|
data/lib/nitro/flash.rb
CHANGED
data/lib/nitro/helper.rb
CHANGED
data/lib/nitro/helper/form.rb
CHANGED
data/lib/nitro/helper/layout.rb
CHANGED
data/lib/nitro/helper/pager.rb
CHANGED
|
@@ -120,12 +120,16 @@ class Pager
|
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
+
# Is the pager empty, ie has one page only?
|
|
124
|
+
|
|
123
125
|
def empty?
|
|
124
|
-
return @
|
|
126
|
+
return @page_count < 1
|
|
125
127
|
end
|
|
126
128
|
|
|
129
|
+
# The items count.
|
|
130
|
+
|
|
127
131
|
def size
|
|
128
|
-
return @
|
|
132
|
+
return @total_count
|
|
129
133
|
end
|
|
130
134
|
|
|
131
135
|
# Returns the range of the current page.
|
|
@@ -271,7 +275,7 @@ private
|
|
|
271
275
|
when Array
|
|
272
276
|
items = items.dup
|
|
273
277
|
pager = Pager.new(request, per_page, items.size, pager_key)
|
|
274
|
-
items = items.slice(pager.offset, pager.per_page)
|
|
278
|
+
items = items.slice(pager.offset, pager.per_page) || []
|
|
275
279
|
return items, pager
|
|
276
280
|
|
|
277
281
|
when Og::Collection
|
data/lib/nitro/helper/rss.rb
CHANGED
data/lib/nitro/render.rb
CHANGED
data/lib/nitro/scaffolding.rb
CHANGED
|
@@ -56,8 +56,13 @@ module Scaffolding
|
|
|
56
56
|
@plural = options[:plural_name]
|
|
57
57
|
@suffix = options[:suffix]
|
|
58
58
|
@compiler = Compiler.new(@controller)
|
|
59
|
+
|
|
59
60
|
@base = options[:base] || options[:mount] || options[:at]
|
|
60
|
-
|
|
61
|
+
if @base == true
|
|
62
|
+
@base = @plural.dup
|
|
63
|
+
elsif @base == :ROOT
|
|
64
|
+
@base = nil
|
|
65
|
+
end
|
|
61
66
|
@base__ = "#{@base}__" if @base
|
|
62
67
|
end
|
|
63
68
|
|
|
@@ -257,6 +262,16 @@ module Scaffolding
|
|
|
257
262
|
# This method modifies both the controller and the
|
|
258
263
|
# scaffolded Class.
|
|
259
264
|
#
|
|
265
|
+
#
|
|
266
|
+
# === Options
|
|
267
|
+
#
|
|
268
|
+
# * base/mount : mountpoint for the action, defines a
|
|
269
|
+
# prefix for the scaffolded action.
|
|
270
|
+
# If mount => true, the prefix is the plural of the
|
|
271
|
+
# scaffolded class name.
|
|
272
|
+
# If mount => :ROOT or nil, the actions are mounted at the
|
|
273
|
+
# root of the controller.
|
|
274
|
+
#
|
|
260
275
|
# === Example
|
|
261
276
|
#
|
|
262
277
|
# scaffold Article
|
|
@@ -278,6 +293,8 @@ module Scaffolding
|
|
|
278
293
|
#--
|
|
279
294
|
# This is the first phase of the scaffolding proccess,
|
|
280
295
|
# scaffold targets are marked, and default options set.
|
|
296
|
+
#
|
|
297
|
+
# FIXME: Rethink the options, make :ROOT the default.
|
|
281
298
|
#++
|
|
282
299
|
|
|
283
300
|
def scaffold(klass, options = {})
|
|
@@ -301,7 +318,7 @@ module Scaffolding
|
|
|
301
318
|
|
|
302
319
|
def compile_scaffolding_code
|
|
303
320
|
# load scaffolding for all og classes if specified
|
|
304
|
-
|
|
321
|
+
|
|
305
322
|
if scaffold_all?
|
|
306
323
|
options = scaffold_all_options
|
|
307
324
|
Og.manager.manageable_classes.each do |klass|
|
|
@@ -320,8 +337,13 @@ module Scaffolding
|
|
|
320
337
|
end
|
|
321
338
|
|
|
322
339
|
#--
|
|
323
|
-
# set the options flag to trigger scaffolding of all classes
|
|
324
|
-
#
|
|
340
|
+
# set the options flag to trigger scaffolding of all classes
|
|
341
|
+
# in second phase.
|
|
342
|
+
# use exclude to ignore classes:
|
|
343
|
+
# scaffold_all :exclude => [Product, Category]
|
|
344
|
+
#
|
|
345
|
+
# gmosx: I do NOT lke this, will remove this in a future
|
|
346
|
+
# version.
|
|
325
347
|
#++
|
|
326
348
|
|
|
327
349
|
def scaffold_all(options = {})
|