Namespace

Files

Padrino::Reloader

High performance source code reloader middleware

Constants

LOADED_CLASSES

The list of object constants and classes loaded as part of the project.

LOADED_FILES

The list of files loaded as part of a project.

MTIMES

The modification times for every file in a project.

Public Class Methods

changed?() click to toggle source

Returns true if any file changes are detected and populates the MTIMES cache

# File lib/padrino-core/reloader.rb, line 91
def changed?
  changed = false
  rotation do |file, mtime|
    new_file = MTIMES[file].nil?
    previous_mtime = MTIMES[file] ||= mtime
    changed = true if new_file || mtime > previous_mtime
  end
  changed
end
Also aliased as: run!
clear!() click to toggle source

Remove files and classes loaded with stat

# File lib/padrino-core/reloader.rb, line 76
def clear!
  MTIMES.clear
  LOADED_CLASSES.each do |file, klasses|
    klasses.each { |klass| remove_constant(klass) }
    LOADED_CLASSES.delete(file)
  end
  LOADED_FILES.each do |file, dependencies|
    dependencies.each { |dependency| $LOADED_FEATURES.delete(dependency) }
    $LOADED_FEATURES.delete(file)
  end
end
exclude() click to toggle source

Specified folders can be excluded from the code reload detection process. Default excluded directories at Padrino.root are: test, spec, features, tmp, config, db and public

# File lib/padrino-core/reloader.rb, line 28
def exclude
  @_exclude ||= %(test spec tmp features config public db).map { |path| Padrino.root(path) }
end
exclude_constants() click to toggle source

Specified constants can be excluded from the code unloading process.

# File lib/padrino-core/reloader.rb, line 35
def exclude_constants
  @_exclude_constants ||= []
end
figure_path(file) click to toggle source

Returns true if the file is defined in our padrino root

# File lib/padrino-core/reloader.rb, line 173
def figure_path(file)
  return file if Pathname.new(file).absolute?
  $:.each do |path|
    found = File.join(path, file)
    return File.expand_path(found) if File.exist?(found)
  end
  file
end
include_constants() click to toggle source

Specified constants can be configured to be reloaded on every request. Default included constants are: [none]

# File lib/padrino-core/reloader.rb, line 43
def include_constants
  @_include_constants ||= []
end
lock!() click to toggle source

We lock dependencies sets to prevent reloading of protected constants

# File lib/padrino-core/reloader.rb, line 105
def lock!
  klasses = ObjectSpace.classes.map { |klass| klass.name.to_s.split("::")[0] }.uniq
  klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class }
  Padrino::Reloader.exclude_constants.concat(klasses)
end
reload!() click to toggle source

Reload all files with changes detected.

# File lib/padrino-core/reloader.rb, line 50
def reload!
  # Detect changed files
  rotation do |file, mtime|
    # Retrive the last modified time
    new_file = MTIMES[file].nil?
    previous_mtime = MTIMES[file] ||= mtime
    logger.devel "Detected a new file #{file}" if new_file
    # We skip to next file if it is not new and not modified
    next unless new_file || mtime > previous_mtime
    # Now we can reload our file
    apps = mounted_apps_of(file)
    if apps.present?
      apps.each { |app| app.app_obj.reload! }
    else
      safe_load(file, :force => new_file)
      # Reload also apps
      Padrino.mounted_apps.each do |app|
        app.app_obj.reload! if app.app_obj.dependencies.include?(file)
      end
    end
  end
end
remove_constant(const) click to toggle source

Removes the specified class and constant.

# File lib/padrino-core/reloader.rb, line 185
def remove_constant(const)
  return if exclude_constants.compact.uniq.any? { |c| (const.to_s =~ %{^#{Regexp.escape(c)}}) } &&
           !include_constants.compact.uniq.any? { |c| (const.to_s =~ %{^#{Regexp.escape(c)}}) }
  begin
    parts  = const.to_s.split("::")
    base   = parts.size == 1 ? Object : parts[0..-2].join("::").constantize
    object = parts[-1].to_s
    base.send(:remove_const, object)
    logger.devel "Removed constant: #{const}"
  rescue NameError; end
end
run!() click to toggle source
Alias for: changed?
safe_load(file, options={}) click to toggle source

A safe Kernel::require which issues the necessary hooks depending on results

# File lib/padrino-core/reloader.rb, line 114
def safe_load(file, options={})
  began_at    = Time.now
  force, file = options[:force], figure_path(file)

  # Check if file was changed or if force a reload
  reload = MTIMES[file] && File.mtime(file) > MTIMES[file]
  return if !force && !reload && MTIMES[file]

  # Removes all classes declared in the specified file
  if klasses = LOADED_CLASSES.delete(file)
    klasses.each { |klass| remove_constant(klass) }
  end

  # Remove all loaded fatures with our file
  if features = LOADED_FILES[file]
    features.each { |feature| $LOADED_FEATURES.delete(feature) }
  end

  # Duplicate objects and loaded features before load file
  klasses = ObjectSpace.classes.dup
  files   = $LOADED_FEATURES.dup

  # Now we can reload dependencies of our file
  if features = LOADED_FILES.delete(file)
    features.each { |feature| safe_load(feature, :force => true) }
  end

  # And finally load the specified file
  begin
    logger.devel :loading, began_at, file if !reload
    logger.debug :reload,  began_at, file if  reload
    $LOADED_FEATURES.delete(file)
    verbosity_was, $-v = $-v, nil
    loaded = false
    require(file)
    loaded = true
    MTIMES[file] = File.mtime(file)
  rescue SyntaxError => e
    logger.error "Cannot require #{file} due to a syntax error: #{e.message}"
  ensure
    $-v = verbosity_was
    new_constants = (ObjectSpace.classes - klasses).uniq
    if loaded
      # Store the file details
      LOADED_CLASSES[file] = new_constants
      LOADED_FILES[file]   = ($LOADED_FEATURES - files - [file]).uniq
      # Track only features in our Padrino.root
      LOADED_FILES[file].delete_if { |feature| !in_root?(feature) }
    else
      logger.devel "Failed to load #{file}; removing partially defined constants"
      new_constants.each { |klass| remove_constant(klass) }
    end

  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.