nitro 0.27.0 → 0.28.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 = {})
|