Class: Vagrant::Action::Warden
- Inherits:
-
Object
- Object
- Vagrant::Action::Warden
- Defined in:
- lib/vagrant/action/warden.rb
Overview
The action warden is a middleware which injects itself between
every other middleware, watching for exceptions which are raised
and performing proper cleanup on every action by calling the recover
method. The warden therefore allows middlewares to not worry about
exceptional events, and by providing a simple callback, can clean up
in any erroneous case.
Warden will "just work" behind the scenes, and is not of particular interest except to those who are curious about the internal workings of Vagrant.
Instance Attribute Summary collapse
-
#actions ⇒ Object
Returns the value of attribute actions.
-
#stack ⇒ Object
Returns the value of attribute stack.
Instance Method Summary collapse
-
#begin_rescue(env) ⇒ Object
Begins the recovery sequence for all middlewares which have run.
- #call(env) ⇒ Object
-
#finalize_action(action, env) ⇒ Object
A somewhat confusing function which simply initializes each middleware properly to call the next middleware in the sequence.
-
#initialize(actions, env) ⇒ Warden
constructor
A new instance of Warden.
Constructor Details
#initialize(actions, env) ⇒ Warden
Returns a new instance of Warden.
18 19 20 21 22 |
# File 'lib/vagrant/action/warden.rb', line 18 def initialize(actions, env) @stack = [] @actions = actions.map { |m| finalize_action(m, env) } @logger = Log4r::Logger.new("vagrant::action::warden") end |
Instance Attribute Details
#actions ⇒ Object
Returns the value of attribute actions.
16 17 18 |
# File 'lib/vagrant/action/warden.rb', line 16 def actions @actions end |
#stack ⇒ Object
Returns the value of attribute stack.
16 17 18 |
# File 'lib/vagrant/action/warden.rb', line 16 def stack @stack end |
Instance Method Details
#begin_rescue(env) ⇒ Object
Begins the recovery sequence for all middlewares which have run.
It does this by calling recover
(if it exists) on each middleware
which has already run, in reverse order.
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/vagrant/action/warden.rb', line 53 def begin_rescue(env) @stack.each do |act| if act.respond_to?(:recover) @logger.info("Calling recover: #{act}") act.recover(env) end end # Clear stack so that warden down the middleware chain doesn't # rescue again. @stack.clear end |
#call(env) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/vagrant/action/warden.rb', line 24 def call(env) return if @actions.empty? begin # Call the next middleware in the sequence, appending to the stack # of "recoverable" middlewares in case something goes wrong! raise Errors::VagrantInterrupt if env[:interrupted] action = @actions.shift @logger.info("Calling action: #{action}") @stack.unshift(action).first.call(env) raise Errors::VagrantInterrupt if env[:interrupted] rescue SystemExit # This means that an "exit" or "abort" was called. In these cases, # we just exit immediately. raise rescue Exception => e @logger.error("Error occurred: #{e}") env["vagrant.error"] = e # Something went horribly wrong. Start the rescue chain then # reraise the exception to properly kick us out of limbo here. begin_rescue(env) raise end end |
#finalize_action(action, env) ⇒ Object
A somewhat confusing function which simply initializes each middleware properly to call the next middleware in the sequence.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/vagrant/action/warden.rb', line 68 def finalize_action(action, env) klass, args, block = action # Default the arguments to an empty array. Otherwise in Ruby 1.8 # a `nil` args will actually pass `nil` into the class. args ||= [] if klass.is_a?(Class) # A action klass which is to be instantiated with the # app, env, and any arguments given klass.new(self, env, *args, &block) elsif klass.respond_to?(:call) # Make it a lambda which calls the item then forwards # up the chain lambda do |e| klass.call(e) self.call(e) end else raise "Invalid action: #{action.inspect}" end end |