/usr/lib/ruby/vendor_ruby/ramaze/reloader.rb is in ruby-ramaze 2012.12.08-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
# All files in this distribution are subject to the terms of the MIT license.
module Ramaze
##
# High performant source reloader
#
# This class acts as Rack middleware.
#
# It does not depend on Ramaze itself, but you might have to adjust the
# Reloader::Hooks module or include your own module to override the hooks.
# You also might have to set the Log constant.
#
# Currently, it uses RInotify if available and falls back to using File.stat.
#
# Please note that this will not reload files in the background, it does so
# only when actively called
# In case of Ramaze it is performing a check/reload cycle at the start of
# every request, but also respects a cool down time, during which nothing will
# be done.
#
# After every reload the OPTIONS hash will be checked for changed options and
# assigned to the instance, so you may change options during the lifetime of
# your application.
#
# A number of hooks will be executed during the reload cycle, see
# Ramaze::ReloaderHooks for more information.
#
class Reloader
OPTIONS = {
# At most check every n seconds
# nil/false will never trigger the reload cycle
# 0 will cycle on every call
:cooldown => 2,
# Compiled files cannot be reloaded during runtime
:ignore => /\.so$/,
# Run cycle in a Thread.exclusive, by default no threads are used.
:thread => false,
# If you assign a block here it will be instance_evaled instead of
# calling cycle. This allows you to use for example EventMachine for
# well performing asynchronous cycling.
:control => nil, # lambda{ cycle },
}
begin
require 'rinotify'
require 'ramaze/reloader/watch_inotify'
Watcher = WatchInotify
rescue LoadError
# stat always available
require 'ramaze/reloader/watch_stat'
Watcher = WatchStat
end
##
# Creates a new instance of the class and saves the application it has to
# watch.
#
# @author Michael Fellinger
# @since 09-08-2008
# @param [Ramaze::App] app The application to monitor.
#
def initialize(app)
@app = app
@files = {}
@watcher = Watcher.new
options_reload
end
##
# Returns all the options for this class.
#
# @author Michael Fellinger
# @since 09-08-2008
# @return [Array]
#
def options_reload
@cooldown, @ignore, @control, @thread =
OPTIONS.values_at(:cooldown, :ignore, :control, :thread)
end
##
# Allows this class to be called as a Rack middleware.
#
# @author Michael Fellinger
# @since 09-08-2008
# @param [Hash] env A hash containing all environment details.
#
def call(env)
options_reload
@watcher.call(@cooldown) do
if @control
instance_eval(&@control)
elsif @thread
Thread.exclusive{ cycle }
else
cycle
end
end
@app.call(env)
end
##
# Loops through all the files and reloads all changes files.
#
# @author Michael Fellinger
# @since 09-08-2008
#
def cycle
before_cycle
rotation{|file| @watcher.watch(file) }
@watcher.changed_files{|f| safe_load(f) }
after_cycle
end
##
# A safe Kernel::load, issuing the hooks depending on the results
#
# @author Michael Fellinger
# @since 09-08-2008
# @param [String] file Path to the file to safely load.
#
def safe_load(file)
before_safe_load(file)
load(file)
after_safe_load_succeed(file)
rescue Object => ex
Log.error(ex)
after_safe_load_failed(file, ex)
end
def rotation
files = [$0, __FILE__, *$LOADED_FEATURES].uniq
paths = ['./', *$LOAD_PATH].uniq
files.each do |file|
next if file =~ @ignore
if not @files.has_key?(file) and path = figure_path(file, paths)
@files[file] = path
yield path
end
end
end
##
# Tries to find a given file in an array of file paths.
#
# @author Michael Fellinger
# @since 09-08-2008
# @param [String] file The name of the file to look for.
# @param [Array] paths An array of paths to search.
# @return [String]
#
def figure_path(file, paths)
if Pathname.new(file).absolute?
return File.exist?(file) ? file : nil
end
paths.each do |possible_path|
full_path = File.join(possible_path, file)
return full_path if File.exist?(full_path)
end
nil
end
# Holds hooks that are called before and after #cycle and #safe_load
module Hooks
# Overwrite to add actions before the reload rotation is started.
def before_cycle; end
# Overwrite to add actions after the reload rotation has ended.
def after_cycle; end
# Overwrite to add actions before a file is Kernel::load-ed
def before_safe_load(file)
Log.debug("reload #{file}")
end
# Overwrite to add actions after a file is Kernel::load-ed successfully,
# by default we clean the Cache for compiled templates and resolved
# actions.
def after_safe_load_succeed(file)
Cache.clear_after_reload
after_safe_load(file)
end
# Overwrite to add custom hook in addition to default Cache cleaning
def after_safe_load(file)
end
# Overwrite to add actions after a file is Kernel::load-ed unsuccessfully,
# by default we output an error-message with the exception.
def after_safe_load_failed(file, error)
Log.error(error)
end
end # Hooks
include Hooks
end # Reloader
end # Ramaze
|