Class: Reactive::Initializer
- Includes:
- Singleton
- Defined in:
- lib/reactive-core/initializer.rb
Overview
Handles Reactive initialization process.
The initialization process is sliced in short parts named stages. Each stage is responsible for a specific initialization. Plugins will also register stages in this system.
Running the application is a three steps process:
-
Booting: loads the reactive-core gem (see config/boot.rb)
-
Initialization (the #run method is called)
-
Dispatching the initial request (as configured in config/config.rb)
The application developer may also register initialization stages by example in the files under config/initializers/*.rb like so:
Reactive::Initializer.init :donuts do
require 'donuts'
Donuts.setup_factory
end
Registering stages is done with the general #register method or the more conveniant methods: #configure, #before_init, #init and #after_init.
The application or any plugin may observe the initilization process by registering an observer with #add_observer. It acts like a callback triggered before processing each stage.
The stages are left visible with the #stages accessor, but be careful with it.
Direct Known Subclasses
Defined Under Namespace
Constant Summary collapse
- STAGE_LEVELS =
{:configure => -400, :before_init => -200, :init => 0, :init_rails_plugin => 100, :after_init => 200}
Instance Attribute Summary collapse
-
#observers ⇒ Object
readonly
:nodoc:.
-
#stages ⇒ Object
readonly
:nodoc:.
Class Method Summary collapse
- .add_observer(proc = nil, &block) ⇒ Object
- .after_init(name, options = {}, &block) ⇒ Object
- .before_init(name, options = {}, &block) ⇒ Object
-
.configure(name, options = {}, &block) ⇒ Object
convenience aliases for standard priorities.
- .init(name, options = {}, &block) ⇒ Object
-
.register(name, options = {}, &block) ⇒ Object
Registers an initialization stage.
-
.run(stage = :final, configuration = Reactive.configuration || Configuration.new) {|configuration| ... } ⇒ Object
Runs the initialization process.
- .stages ⇒ Object
Instance Method Summary collapse
-
#initialize ⇒ Initializer
constructor
:nodoc:.
-
#register(name, options, &block) ⇒ Object
:nodoc:.
-
#run_stages(last_stage) ⇒ Object
last_stage is either a level which WILL also be processed or a stage name that WILL also be processed.
Constructor Details
#initialize ⇒ Initializer
:nodoc:
283 284 285 286 287 |
# File 'lib/reactive-core/initializer.rb', line 283 def initialize # :nodoc: @stages = [] @finished = [] @observers = [] end |
Instance Attribute Details
#observers ⇒ Object (readonly)
:nodoc:
281 282 283 |
# File 'lib/reactive-core/initializer.rb', line 281 def observers @observers end |
#stages ⇒ Object (readonly)
:nodoc:
281 282 283 |
# File 'lib/reactive-core/initializer.rb', line 281 def stages @stages end |
Class Method Details
.add_observer(proc = nil, &block) ⇒ Object
258 259 260 261 262 |
# File 'lib/reactive-core/initializer.rb', line 258 def add_observer(proc = nil, &block) raise ArgumentError, "Pass either a proc or a block, not both!" unless proc.nil? ^ block.nil? raise ArgumentError, "Passed object is not callable!" if proc && !proc.respond_to?(:call) Initializer.instance.observers << (proc || block) end |
.after_init(name, options = {}, &block) ⇒ Object
243 244 245 246 |
# File 'lib/reactive-core/initializer.rb', line 243 def after_init(name, = {}, &block) name = "after_init_#{name}" unless name.to_s =~ /^after_init_/ register(name, :after_init, &block) end |
.before_init(name, options = {}, &block) ⇒ Object
233 234 235 236 |
# File 'lib/reactive-core/initializer.rb', line 233 def before_init(name, = {}, &block) name = "before_init_#{name}" unless name.to_s =~ /^before_init_/ register(name, :before_init, &block) end |
.configure(name, options = {}, &block) ⇒ Object
convenience aliases for standard priorities
228 229 230 231 |
# File 'lib/reactive-core/initializer.rb', line 228 def configure(name, = {}, &block) name = "configure_#{name}" unless name.to_s =~ /^configure_/ register(name, :configure, &block) end |
.init(name, options = {}, &block) ⇒ Object
238 239 240 241 |
# File 'lib/reactive-core/initializer.rb', line 238 def init(name, = {}, &block) name = "init_#{name}" unless name.to_s =~ /^init_/ register(name, :init, &block) end |
.register(name, options = {}, &block) ⇒ Object
Registers an initialization stage. Pass a name, then either a level or an option to specify the relation against another stage.
register(:mvc_configure, -100) { some_code }
register(:mvc_configure, :before => :init_logger) { some_code }
register(:mvc_configure, :after => :wx_configure, :proc => a_proc)
223 224 225 |
# File 'lib/reactive-core/initializer.rb', line 223 def register(name, = {}, &block) Initializer.instance.register(name, , &block) end |
.run(stage = :final, configuration = Reactive.configuration || Configuration.new) {|configuration| ... } ⇒ Object
Runs the initialization process.
stage is either a level which will also be processed or a stage name that will also be processed.
252 253 254 255 256 |
# File 'lib/reactive-core/initializer.rb', line 252 def run(stage = :final, configuration = Reactive.configuration || Configuration.new) # :yields: configuration yield configuration if block_given? Reactive.configuration = configuration Initializer.instance.run_stages(stage) end |
.stages ⇒ Object
264 265 266 |
# File 'lib/reactive-core/initializer.rb', line 264 def stages Initializer.instance.stages end |
Instance Method Details
#register(name, options, &block) ⇒ Object
:nodoc:
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/reactive-core/initializer.rb', line 289 def register(name, , &block) # :nodoc: = .is_a?(Hash) ? : {:level => STAGE_LEVELS[] || } proc = [:proc] raise ArgumentError, "Pass either a proc or a block, not both!" unless proc.nil? ^ block.nil? raise ArgumentError, "Proc object is not callable!" if proc && !proc.respond_to?(:call) block ||= proc # raise ArgumentError, "register options are mutually exclusive!" if options[:level] case when level = [:level] insert_index = stages.index(stages.find {|item| item.level > level}) || -1 when before = [:before] insert_index = stages.index(stages.find{|item| item.name == before.to_sym}) raise ArgumentError, "Can't insert before '#{before}', no stage of that name!" unless insert_index items = [insert_index-1 < 0 ? nil : insert_index-1, insert_index].compact level = stages.values_at(*items).inject {|sum, stage| sum + stage.level} / items.size when after = [:after] insert_index = stages.index(stages.find{|item| item.name == after.to_sym}) raise ArgumentError, "Can't insert after '#{after}', no stage of that name!" unless insert_index items = stages.values_at([index, index+1]).compact level = items.inject {|sum, stage| sum + stage.level} / items.size end stages.insert(insert_index, Stage.new(name, level, block)) end |
#run_stages(last_stage) ⇒ Object
last_stage is either a level which WILL also be processed or a stage name that WILL also be processed.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/reactive-core/initializer.rb', line 316 def run_stages(last_stage) # :nodoc: last_stage = STAGE_LEVELS[last_stage] || last_stage stage = stages.first while stage break if last_stage.is_a?(Integer) && stage.level > last_stage unless @finished.include? stage observers.each {|block| block.call(stage) } benchlog("Stage: #{stage.name}") { stage.proc.call } @finished << stage break if stage.name == last_stage end stage = stages[stages.index(stage).succ] end end |