manveru-ramaze 2008.12 → 2009.01
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/lib/proto/public/.htaccess +24 -0
- data/lib/ramaze/action/render.rb +6 -5
- data/lib/ramaze/controller/resolve.rb +2 -2
- data/lib/ramaze/current/request.rb +2 -2
- data/lib/ramaze/helper/bench.rb +43 -0
- data/lib/ramaze/helper/markaby.rb +1 -1
- data/lib/ramaze/helper/paginate.rb +1 -1
- data/lib/ramaze/option.rb +1 -1
- data/lib/ramaze/reloader/watch_inotify.rb +42 -30
- data/lib/ramaze/reloader/watch_stat.rb +1 -5
- data/lib/ramaze/reloader.rb +1 -1
- data/lib/ramaze/version.rb +1 -1
- data/ramaze.gemspec +3 -167
- metadata +4 -168
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# General Apache options
|
|
2
|
+
Options +FollowSymLinks +ExecCGI
|
|
3
|
+
AddHandler cgi-script cgi rb
|
|
4
|
+
<IfModule mod_fastcgi.c>
|
|
5
|
+
AddHandler fastcgi-script fcgi
|
|
6
|
+
</IfModule>
|
|
7
|
+
<IfModule mod_fcgid.c>
|
|
8
|
+
AddHandler fcgid-script fcgi
|
|
9
|
+
</IfModule>
|
|
10
|
+
|
|
11
|
+
# Redirect all requests not available on the filesystem to Ramaze.
|
|
12
|
+
|
|
13
|
+
RewriteEngine On
|
|
14
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
|
15
|
+
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
|
|
16
|
+
|
|
17
|
+
# In case Ramaze experiences terminal errors.
|
|
18
|
+
# Instead of displaying this message you can supply a
|
|
19
|
+
# file here which will be rendered instead.
|
|
20
|
+
#
|
|
21
|
+
# Example:
|
|
22
|
+
# ErrorDocument 500 /500.html
|
|
23
|
+
|
|
24
|
+
ErrorDocument 500 "<h2>Application error</h2>Ramaze failed to start properly"
|
data/lib/ramaze/action/render.rb
CHANGED
|
@@ -49,8 +49,8 @@ module Ramaze
|
|
|
49
49
|
# true.
|
|
50
50
|
|
|
51
51
|
def cached_render
|
|
52
|
-
if Global.file_cache
|
|
53
|
-
cached_render_file
|
|
52
|
+
if cache_root = Global.file_cache
|
|
53
|
+
cached_render_file(cache_root)
|
|
54
54
|
else
|
|
55
55
|
cached_render_memory
|
|
56
56
|
end
|
|
@@ -59,12 +59,13 @@ module Ramaze
|
|
|
59
59
|
# Uses files in the Global.public_root to provide a static ressource on
|
|
60
60
|
# next request and returns the rendered action
|
|
61
61
|
|
|
62
|
-
def cached_render_file
|
|
62
|
+
def cached_render_file(cache_root)
|
|
63
63
|
rendered = uncached_render
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
cr = cache_root.respond_to?(:to_str) ? cache_root.to_str : Global.public_root
|
|
66
|
+
global_epath = File.join(cr, self.controller.mapping, extended_path)
|
|
66
67
|
FileUtils.mkdir_p(File.dirname(global_epath))
|
|
67
|
-
File.open(global_epath, 'w+')
|
|
68
|
+
File.open(global_epath, 'w+'){|fp| fp.print(rendered) }
|
|
68
69
|
|
|
69
70
|
rendered
|
|
70
71
|
end
|
|
@@ -16,7 +16,7 @@ module Ramaze
|
|
|
16
16
|
# instead, in either case with path as argument.
|
|
17
17
|
|
|
18
18
|
def resolve(path, routed = false)
|
|
19
|
-
|
|
19
|
+
Thread.current[:routed] = routed
|
|
20
20
|
|
|
21
21
|
FILTER.each do |filter|
|
|
22
22
|
answer = if filter.respond_to?(:call)
|
|
@@ -90,7 +90,7 @@ module Ramaze
|
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
if
|
|
93
|
+
if !Thread.current[:routed] and new_path = Route.resolve(path)
|
|
94
94
|
Log.dev("Routing from `#{path}' to `#{new_path}'")
|
|
95
95
|
return resolve(new_path, true)
|
|
96
96
|
end
|
|
@@ -196,9 +196,9 @@ module Ramaze
|
|
|
196
196
|
# Example:
|
|
197
197
|
# request.params
|
|
198
198
|
# # => {'name' => 'jason', 'age' => '45', 'job' => 'lumberjack'}
|
|
199
|
-
# request.
|
|
199
|
+
# request.subset('name')
|
|
200
200
|
# # => {'name' => 'jason'}
|
|
201
|
-
# request.
|
|
201
|
+
# request.subset(:name, :job)
|
|
202
202
|
# # => {'name' => 'jason', 'job' => 'lumberjack'}
|
|
203
203
|
|
|
204
204
|
def subset(*keys)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'benchmark'
|
|
2
|
+
|
|
3
|
+
module Ramaze
|
|
4
|
+
module Helper
|
|
5
|
+
|
|
6
|
+
# Little helper to give you a hand when benching parts of actions
|
|
7
|
+
|
|
8
|
+
module Bench
|
|
9
|
+
|
|
10
|
+
# Will first run an empty loop to determine the overhead it imposes, then
|
|
11
|
+
# goes on to yield your block +iterations+ times.
|
|
12
|
+
#
|
|
13
|
+
# The last yielded return value will be returned upon completion of the
|
|
14
|
+
# benchmark and the result of the benchmark itself will be sent to
|
|
15
|
+
# Log.info
|
|
16
|
+
#
|
|
17
|
+
# Example:
|
|
18
|
+
#
|
|
19
|
+
# class MainController < Ramaze::Controller
|
|
20
|
+
# def index
|
|
21
|
+
# @users = bench{ User.all }
|
|
22
|
+
# @tags = bench{ Article.tags }
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# This will show something like following in your log:
|
|
27
|
+
# [..] INFO Bench ./start.rb:3:in `index': 0.121163845062256
|
|
28
|
+
# [..] INFO Bench ./start.rb:4:in `index': 2.234987235098341
|
|
29
|
+
#
|
|
30
|
+
# So now we know that the Article.tags call takes the most time and
|
|
31
|
+
# should be improved.
|
|
32
|
+
|
|
33
|
+
def bench(iterations = 1)
|
|
34
|
+
result = nil
|
|
35
|
+
from = caller[0]
|
|
36
|
+
delta = Benchmark.realtime{ iterations.times{ nil }}
|
|
37
|
+
taken = Benchmark.realtime{ iterations.times{ result = yield }}
|
|
38
|
+
Log.info "Bench #{from}: #{taken - delta}"
|
|
39
|
+
return result
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -15,7 +15,7 @@ module Ramaze
|
|
|
15
15
|
def markaby(ivs = {}, helpers = nil, &block)
|
|
16
16
|
builder = ::Markaby::Builder
|
|
17
17
|
builder.extend(Ramaze::Helper::Methods)
|
|
18
|
-
builder.send(:helper, :link)
|
|
18
|
+
builder.send(:helper, :redirect, :link, :sendfile, :flash, :cgi, :partial)
|
|
19
19
|
|
|
20
20
|
iv_hash = {}
|
|
21
21
|
instance_variables.each do |iv|
|
|
@@ -165,7 +165,7 @@ module Ramaze
|
|
|
165
165
|
text = h(text.to_s)
|
|
166
166
|
|
|
167
167
|
params = Ramaze::Request.current.params.merge(@var.to_s => n)
|
|
168
|
-
name = Ramaze::Request.current.
|
|
168
|
+
name = Ramaze::Request.current.path_info
|
|
169
169
|
hash[:href] = R(name, params)
|
|
170
170
|
|
|
171
171
|
g.a(hash){ text }
|
data/lib/ramaze/option.rb
CHANGED
|
@@ -78,7 +78,7 @@ module Ramaze
|
|
|
78
78
|
o "Turn on customized error pages. Use Rack::ShowException otherwise.",
|
|
79
79
|
:error_page, true, :cli => true
|
|
80
80
|
|
|
81
|
-
o "
|
|
81
|
+
o "Cache actions to filesystem, uses String as directory name or Global.public_root if other truism",
|
|
82
82
|
:file_cache, false, :cli => false
|
|
83
83
|
|
|
84
84
|
o "Specify what IP Ramaze will respond to - 0.0.0.0 for all",
|
|
@@ -1,57 +1,62 @@
|
|
|
1
1
|
module Ramaze
|
|
2
2
|
class Reloader
|
|
3
|
+
# TODO:
|
|
4
|
+
# * There seems to be a problem somewhere that I couldn't identify yet, a
|
|
5
|
+
# file has to be modified twice initially to make it show up as
|
|
6
|
+
# modified here, subsequent changes work just fine.
|
|
7
|
+
# The only workaround I could find right now would be to read/write
|
|
8
|
+
# every single file, but that would be unexpected, irresponsible, and
|
|
9
|
+
# error-prone.
|
|
10
|
+
#
|
|
11
|
+
# NOTE:
|
|
12
|
+
# * I have changed from using a Mutex to using a Queue, which uses a
|
|
13
|
+
# Mutex internally.
|
|
14
|
+
|
|
3
15
|
class WatchInotify
|
|
4
16
|
POLL_INTERVAL = 2 # seconds
|
|
17
|
+
NOTIFY_MASK = RInotify::MODIFY | RInotify::IN_ONESHOT
|
|
5
18
|
|
|
6
19
|
def initialize
|
|
7
20
|
@watcher = RInotify.new
|
|
8
|
-
@changed =
|
|
9
|
-
@mutex = Mutex.new
|
|
21
|
+
@changed = Queue.new
|
|
10
22
|
@watcher_thread = start_watcher
|
|
11
23
|
end
|
|
12
24
|
|
|
13
25
|
def call(cooldown)
|
|
14
|
-
yield
|
|
26
|
+
yield
|
|
15
27
|
end
|
|
16
28
|
|
|
17
29
|
# TODO: define a finalizer to cleanup? -- reloader never calls #close
|
|
18
30
|
|
|
19
31
|
def start_watcher
|
|
20
|
-
Thread.new
|
|
21
|
-
loop do
|
|
22
|
-
watcher_cycle
|
|
23
|
-
sleep POLL_INTERVAL
|
|
24
|
-
end
|
|
25
|
-
end
|
|
32
|
+
Thread.new{ loop{ watcher_cycle }}
|
|
26
33
|
end
|
|
27
34
|
|
|
35
|
+
# Not much work here, we just have to empty the event queue and push the
|
|
36
|
+
# descriptors for reloading on next request.
|
|
28
37
|
def watcher_cycle
|
|
29
|
-
return unless @watcher.wait_for_events(
|
|
30
|
-
changed_descriptors = []
|
|
38
|
+
return unless @watcher.wait_for_events(POLL_INTERVAL)
|
|
31
39
|
|
|
32
40
|
@watcher.each_event do |event|
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
@mutex.synchronize do
|
|
37
|
-
changed_descriptors.each do |descriptor|
|
|
38
|
-
@changed << @watcher.watch_descriptors[descriptor]
|
|
39
|
-
end
|
|
41
|
+
@changed.push(event.watch_descriptor)
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
def watch(file)
|
|
44
|
-
return
|
|
45
|
-
return
|
|
46
|
+
return if @watcher.watch_descriptors.has_value?(file)
|
|
47
|
+
return unless File.exist?(file)
|
|
46
48
|
|
|
47
|
-
@
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
@watcher.add_watch(file, NOTIFY_MASK)
|
|
50
|
+
rescue Errno::ENOENT
|
|
51
|
+
retry
|
|
50
52
|
end
|
|
51
53
|
|
|
54
|
+
# FIXME:
|
|
55
|
+
# Seems like this won't work due to some bug in the rinotify library.
|
|
56
|
+
# Would be cool if someone could make a FFI version.
|
|
57
|
+
|
|
52
58
|
def remove_watch(file)
|
|
53
|
-
@
|
|
54
|
-
true
|
|
59
|
+
@watcher.rm_watch(file)
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
def close
|
|
@@ -60,13 +65,20 @@ module Ramaze
|
|
|
60
65
|
true
|
|
61
66
|
end
|
|
62
67
|
|
|
68
|
+
# NOTE:
|
|
69
|
+
# We have to add the changed file again after we got a notification, I
|
|
70
|
+
# have no idea why, but using IN_ONESHOT should make sure that there is
|
|
71
|
+
# no memory leak in the C level even if we add a file again.
|
|
72
|
+
# There is a memory leak however in the watch_descriptors hash, since
|
|
73
|
+
# rinotify won't synchronize the contents properly and will only add to
|
|
74
|
+
# the hash, so we have to clean up ourselves.
|
|
63
75
|
def changed_files
|
|
64
|
-
@
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
until @changed.empty?
|
|
77
|
+
descriptor = @changed.shift
|
|
78
|
+
file = @watcher.watch_descriptors.delete(descriptor)
|
|
79
|
+
watch(file)
|
|
80
|
+
yield(file)
|
|
67
81
|
end
|
|
68
|
-
@tmp.uniq!
|
|
69
|
-
@tmp
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
end
|
|
@@ -38,18 +38,14 @@ module Ramaze
|
|
|
38
38
|
|
|
39
39
|
# return files changed since last call
|
|
40
40
|
def changed_files
|
|
41
|
-
changed = []
|
|
42
|
-
|
|
43
41
|
@files.each do |file, stat|
|
|
44
42
|
if new_stat = safe_stat(file)
|
|
45
43
|
if new_stat.mtime > stat.mtime
|
|
46
|
-
changed << file
|
|
47
44
|
@files[file] = new_stat
|
|
45
|
+
yield(file)
|
|
48
46
|
end
|
|
49
47
|
end
|
|
50
48
|
end
|
|
51
|
-
|
|
52
|
-
changed
|
|
53
49
|
end
|
|
54
50
|
|
|
55
51
|
def safe_stat(file)
|
data/lib/ramaze/reloader.rb
CHANGED
data/lib/ramaze/version.rb
CHANGED