Class: Rack::Unreloader
- Inherits:
-
Object
- Object
- Rack::Unreloader
- Defined in:
- lib/rack/unreloader.rb,
lib/rack/unreloader/reloader.rb
Overview
Reloading application that unloads constants before reloading the relevant files, calling the new rack app if it gets reloaded.
Defined Under Namespace
Classes: Reloader
Constant Summary collapse
- MUTEX =
Mutex used to synchronize reloads
Monitor.new
- F =
Reference to ::File as File would return Rack::File by default.
::File
Instance Attribute Summary collapse
-
#reloader ⇒ Object
readonly
The Rack::Unreloader::Reloader instead related to this instance, if one.
Class Method Summary collapse
-
.expand_directory_paths(paths) ⇒ Object
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.
-
.expand_paths(paths) ⇒ Object
Given the path glob or array of path globs, find all matching files or directories, and return an array of expanded paths.
-
.ruby_files(dir) ⇒ Object
The .rb files in the given directory or any subdirectory.
Instance Method Summary collapse
-
#call(env) ⇒ Object
If the cooldown time has been passed, reload any application files that have changed.
-
#initialize(opts = {}, &block) ⇒ Unreloader
constructor
Setup the reloader.
-
#record_dependency(dependency, *files) ⇒ Object
Records that each path in
files
depends ondependency
. -
#record_split_class(main_file, *files) ⇒ Object
Record that a class is split into multiple files.
-
#reload! ⇒ Object
Reload the application, checking for changed files and reloading them.
-
#require(paths, &block) ⇒ Object
Add a file glob or array of file globs to monitor for changes.
Constructor Details
#initialize(opts = {}, &block) ⇒ Unreloader
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.
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rack/unreloader.rb', line 57 def initialize(opts={}, &block) @app_block = block if opts.fetch(:reload, true) @cooldown = opts.fetch(:cooldown, 1) @last = Time.at(0) Kernel.require 'rack/unreloader/reloader' @reloader = Reloader.new(opts) reload! else @reloader = @cooldown = false end end |
Instance Attribute Details
#reloader ⇒ Object (readonly)
The Rack::Unreloader::Reloader instead related to this instance, if one.
44 45 46 |
# File 'lib/rack/unreloader.rb', line 44 def reloader @reloader end |
Class Method Details
.expand_directory_paths(paths) ⇒ Object
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.
17 18 19 20 21 |
# File 'lib/rack/unreloader.rb', line 17 def self.(paths) (paths). map{|f| F.directory?(f) ? ruby_files(f) : f}. flatten end |
.expand_paths(paths) ⇒ Object
Given the path glob or array of path globs, find all matching files or directories, and return an array of expanded paths.
25 26 27 28 29 30 31 32 |
# File 'lib/rack/unreloader.rb', line 25 def self.(paths) Array(paths). flatten. map{|path| Dir.glob(path).sort_by{|filename| filename.count('/')}}. flatten. map{|path| F.(path)}. uniq end |
.ruby_files(dir) ⇒ Object
The .rb files in the given directory or any subdirectory.
35 36 37 38 39 40 41 |
# File 'lib/rack/unreloader.rb', line 35 def self.ruby_files(dir) files = [] Find.find(dir) do |f| files << f if f =~ /\.rb\z/ end files.sort end |
Instance Method Details
#call(env) ⇒ Object
If the cooldown time has been passed, reload any application files that have changed. Call the app with the environment.
72 73 74 75 76 77 78 |
# File 'lib/rack/unreloader.rb', line 72 def call(env) if @cooldown && Time.now > @last + @cooldown MUTEX.synchronize{reload!} @last = Time.now end @app_block.call.call(env) end |
#record_dependency(dependency, *files) ⇒ Object
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.
93 94 95 96 97 98 99 100 |
# File 'lib/rack/unreloader.rb', line 93 def record_dependency(dependency, *files) if @reloader files = Unreloader.(files) Unreloader.(dependency).each do |path| @reloader.record_dependency(path, files) end end end |
#record_split_class(main_file, *files) ⇒ Object
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.
105 106 107 108 109 110 111 112 113 |
# File 'lib/rack/unreloader.rb', line 105 def record_split_class(main_file, *files) if @reloader files = Unreloader.(files) files.each do |file| record_dependency(file, main_file) end @reloader.skip_reload(files) end end |
#reload! ⇒ Object
Reload the application, checking for changed files and reloading them.
116 117 118 |
# File 'lib/rack/unreloader.rb', line 116 def reload! @reloader.reload! if @reloader end |
#require(paths, &block) ⇒ Object
Add a file glob or array of file globs to monitor for changes.
81 82 83 84 85 86 87 |
# File 'lib/rack/unreloader.rb', line 81 def require(paths, &block) if @reloader @reloader.require_dependencies(paths, &block) else Unreloader.(paths).each{|f| super(f)} end end |