Module: Tennpipes::Loader

Included in:
Tennpipes
Defined in:
lib/tennpipes-base/loader.rb

Instance Method Summary collapse

Instance Method Details

#after_load { ... } ⇒ Array<Proc>

Hooks to be called after a load/reload.

Examples:

after_load do
  DataMapper.finalize
end

Yields:

  • The given block will be called after Tennpipes was loaded/reloaded.

Returns:

  • (Array<Proc>)

    The load/reload hooks.



37
38
39
40
41
# File 'lib/tennpipes-base/loader.rb', line 37

def after_load(&block)
  @_after_load ||= []
  @_after_load << block if block_given?
  @_after_load
end

#before_load { ... } ⇒ Array<Proc>

Hooks to be called before a load/reload.

Examples:

before_load do
  pre_initialize_something
end

Yields:

  • The given block will be called before Tennpipes was loaded/reloaded.

Returns:

  • (Array<Proc>)

    The load/reload before hooks.



17
18
19
20
21
# File 'lib/tennpipes-base/loader.rb', line 17

def before_load(&block)
  @_before_load ||= []
  @_before_load << block if block_given?
  @_before_load
end

#called_fromObject

This adds the ability to instantiate Tennpipes.load! after Application definition.



107
108
109
# File 'lib/tennpipes-base/loader.rb', line 107

def called_from
  @_called_from || first_caller
end

#clear!NilClass

Clear the tennpipes env.

Returns:

  • (NilClass)


82
83
84
85
86
87
88
89
90
91
# File 'lib/tennpipes-base/loader.rb', line 82

def clear!
  clear_middleware!
  mounted_apps.clear
  @_dependency_paths = nil
  before_load.clear
  after_load.clear
  global_configurations.clear
  Reloader.clear!
  Thread.current[:tennpipes_loaded] = nil
end

#dependency_pathsArray<String>

Returns default list of path globs to load as dependencies. Appends custom dependency patterns to the be loaded for Tennpipes.

Examples:

Tennpipes.dependency_paths << "#{Tennpipes.root}/uploaders/*.rb"

Returns:

  • (Array<String>)

    The dependencey paths.



182
183
184
# File 'lib/tennpipes-base/loader.rb', line 182

def dependency_paths
  @_dependency_paths ||= default_dependency_paths + modules_dependency_paths
end

#load!Boolean

Requires necessary dependencies as well as application files from root lib and models.

Returns:

  • (Boolean)

    returns true if Tennpipes is not already bootstraped otherwise else.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/tennpipes-base/loader.rb', line 50

def load!
  return false if loaded?
  began_at = Time.now
  @_called_from = first_caller
  set_encoding
  Tennpipes.logger
  Reloader.lock!
  before_load.each(&:call)
  require_dependencies(*dependency_paths)
  after_load.each(&:call)
  logger.devel "Loaded Tennpipes in #{Time.now - began_at} seconds"
  precompile_all_routes!
  Thread.current[:tennpipes_loaded] = true
end

#loaded?Boolean

Determines whether Tennpipes was loaded with Tennpipes.load!.

Returns:

  • (Boolean)

    Specifies whether Tennpipes was loaded.



117
118
119
# File 'lib/tennpipes-base/loader.rb', line 117

def loaded?
  Thread.current[:tennpipes_loaded]
end

#precompile_all_routes!Object

Precompiles all routes if :precompile_routes is set to true



68
69
70
71
72
73
74
75
# File 'lib/tennpipes-base/loader.rb', line 68

def precompile_all_routes!
  mounted_apps.each do |app|
    app_obj = app.app_obj
    next unless app_obj.respond_to?(:precompile_routes?) && app_obj.precompile_routes?
    app_obj.setup_application!
    logger.devel "Precompiled routes of #{app_obj} (routes size #{app_obj.compiled_router.routes.size})"
  end
end

#reload!Object

Method for reloading required applications and their files.



96
97
98
99
100
101
# File 'lib/tennpipes-base/loader.rb', line 96

def reload!
  return unless Reloader.changed?
  before_load.each(&:call)
  Reloader.reload!
  after_load.each(&:call)
end

#require_dependencies(*paths) ⇒ Object

Attempts to require all dependency libs that we need. If you use this method we can perform correctly a Tennpipes.reload! Another good thing that this method are dependency check, for example:

# models
#  \-- a.rb => require something of b.rb
#  \-- b.rb

In the example above if we do:

Dir["/models/*.rb"].each { |r| require r }

We get an error, because we try to require first a.rb that need something of b.rb.

With this method we don’t have this problem.

Examples:

For require all our app libs we need to do:

require_dependencies("#{Tennpipes.root}/lib/**/*.rb")

Parameters:

  • paths (Array<String>)

    The paths to require.



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
# File 'lib/tennpipes-base/loader.rb', line 145

def require_dependencies(*paths)
  options = paths.extract_options!.merge( :cyclic => true )
  files = paths.flatten.flat_map{ |path| Dir.glob(path).sort_by{ |filename| filename.count('/') } }.uniq

  until files.empty?
    error = fatal = loaded = nil

    files.dup.each do |file|
      begin
        Reloader.safe_load(file, options)
        files.delete(file)
        loaded = true
      rescue NameError, LoadError => error
        logger.devel "Cyclic dependency reload for #{error.class}: #{error.message}"
      rescue Exception => fatal
        break
      end
    end

    if fatal || !loaded
      exception = fatal || error
      logger.exception exception, :short
      raise exception
    end
  end
end