class Rack::Unreloader

Reloading application that unloads constants before reloading the relevant files, calling the new rack app if it gets reloaded.

Constants

F

Reference to ::File as File would return Rack::File by default.

MUTEX

Mutex used to synchronize reloads

Attributes

reloader[R]

The Rack::Unreloader::Reloader instead related to this instance, if one.

Public Class Methods

expand_directory_paths(paths) click to toggle source

Given the list of paths, find all matching files, or matching ruby files in subdirecories if given a directory, and return an array of expanded paths.

   # File lib/rack/unreloader.rb
17 def self.expand_directory_paths(paths)
18   expand_paths(paths).
19     map{|f| F.directory?(f) ? ruby_files(f) : f}.
20     flatten
21 end
expand_paths(paths) click to toggle source

Given the path glob or array of path globs, find all matching files or directories, and return an array of expanded paths.

   # File lib/rack/unreloader.rb
25 def self.expand_paths(paths)
26   Array(paths).
27     flatten.
28     map{|path| Dir.glob(path).sort_by{|filename| filename.count('/')}}.
29     flatten.
30     map{|path| F.expand_path(path)}.
31     uniq
32 end
new(opts={}, &block) click to toggle source

Setup the reloader. Options:

:cooldown

The number of seconds to wait between checks for changed files. Defaults to 1. Set to nil/false to not check for changed files.

:reload

Set to false to not setup a reloader, and just have require work directly. Should be set to false in production mode.

:logger

A Logger instance which will log information related to reloading.

:subclasses

A string or array of strings of class names that should be unloaded. Any classes that are not subclasses of these classes will not be unloaded. This also handles modules, but module names given must match exactly, since modules don't have superclasses.

   # File lib/rack/unreloader.rb
57 def initialize(opts={}, &block)
58   @app_block = block
59   if opts.fetch(:reload, true)
60     @cooldown = opts.fetch(:cooldown, 1)
61     @handle_reload_errors = opts[:handle_reload_errors]
62     @last = Time.at(0)
63     Kernel.require 'rack/unreloader/reloader'
64     @reloader = Reloader.new(opts)
65     reload!
66   else
67     @reloader = @cooldown = @handle_reload_errors = false
68   end
69 end
ruby_files(dir) click to toggle source

The .rb files in the given directory or any subdirectory.

   # File lib/rack/unreloader.rb
35 def self.ruby_files(dir)
36   files = []
37   Find.find(dir) do |f|
38     files << f if f =~ /\.rb\z/
39   end
40   files.sort
41 end

Public Instance Methods

call(env) click to toggle source

If the cooldown time has been passed, reload any application files that have changed. Call the app with the environment.

   # File lib/rack/unreloader.rb
73 def call(env)
74   if @cooldown && Time.now > @last + @cooldown
75     begin
76       MUTEX.synchronize{reload!}
77     rescue StandardError, ScriptError => e
78       raise unless @handle_reload_errors
79       content = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
80       return [500, {'Content-Type' => 'text/plain', 'Content-Length' => content.bytesize.to_s}, [content]]
81     end
82     @last = Time.now
83   end
84   @app_block.call.call(env)
85 end
record_dependency(dependency, *files) click to toggle source

Records that each path in files depends on dependency. If there is a modification to dependency, all related files will be reloaded after dependency is reloaded. Both dependency and each entry in files can be an array of path globs.

    # File lib/rack/unreloader.rb
100 def record_dependency(dependency, *files)
101   if @reloader
102     files = Unreloader.expand_paths(files)
103     Unreloader.expand_paths(dependency).each do |path|
104       @reloader.record_dependency(path, files)
105     end
106   end
107 end
record_split_class(main_file, *files) click to toggle source

Record that a class is split into multiple files. main_file should be the main file for the class, which should require all of the other files. files should be a list of all other files that make up the class.

    # File lib/rack/unreloader.rb
112 def record_split_class(main_file, *files)
113   if @reloader
114     files = Unreloader.expand_paths(files)
115     files.each do |file|
116       record_dependency(file, main_file)
117     end
118     @reloader.skip_reload(files)
119   end
120 end
reload!() click to toggle source

Reload the application, checking for changed files and reloading them.

    # File lib/rack/unreloader.rb
123 def reload!
124   @reloader.reload! if @reloader
125 end
require(paths, &block) click to toggle source

Add a file glob or array of file globs to monitor for changes.

Calls superclass method
   # File lib/rack/unreloader.rb
88 def require(paths, &block)
89   if @reloader
90     @reloader.require_dependencies(paths, &block)
91   else
92     Unreloader.expand_directory_paths(paths).each{|f| super(f)}
93   end
94 end
strip_path_prefix(path_prefix, opts={}) click to toggle source

Strip the given path prefix from all absolute paths used by the reloader. This is designed when chrooting an application.

Options:

:strip_core

Also strips the path prefix from $LOADED_FEATURES and

$LOAD_PATH.
    # File lib/rack/unreloader.rb
133 def strip_path_prefix(path_prefix, opts={})
134   if @reloader
135     @reloader.strip_path_prefix(path_prefix)
136   end
137 end