Class: Vagrant::Action::Builtin::Lock
- Inherits:
-
Object
- Object
- Vagrant::Action::Builtin::Lock
- Defined in:
- lib/vagrant/action/builtin/lock.rb
Overview
This class creates a multi-process lock using ‘flock`. The lock is active for the remainder of the middleware stack.
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, env, options = nil) ⇒ Lock
constructor
A new instance of Lock.
Constructor Details
#initialize(app, env, options = nil) ⇒ Lock
Returns a new instance of Lock.
9 10 11 12 13 14 15 |
# File 'lib/vagrant/action/builtin/lock.rb', line 9 def initialize(app, env, =nil) @app = app @logger = Log4r::Logger.new("vagrant::action::builtin::lock") @options ||= || {} raise ArgumentError, "Please specify a lock path" if !@options[:path] raise ArgumentError, "Please specify an exception." if !@options[:exception] end |
Instance Method Details
#call(env) ⇒ Object
17 18 19 20 21 22 23 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 49 50 51 52 53 |
# File 'lib/vagrant/action/builtin/lock.rb', line 17 def call(env) lock_path = @options[:path] lock_path = lock_path.call(env) if lock_path.is_a?(Proc) env_key = "has_lock_#{lock_path}" if !env[env_key] # If we already have the key in our environment we assume the # lock is held by our middleware stack already and we allow # nesting. File.open(lock_path, "w+") do |f| # The file locking fails only if it returns "false." If it # succeeds it returns a 0, so we must explicitly check for # the proper error case. @logger.info("Locking: #{lock_path}") if f.flock(File::LOCK_EX | File::LOCK_NB) === false exception = @options[:exception] exception = exception.call(env) if exception.is_a?(Proc) raise exception end # Set that we gained the lock and call deeper into the # middleware, but make sure we UNSET the lock when we leave. begin env[env_key] = true @app.call(env) ensure @logger.info("Unlocking: #{lock_path}") env[env_key] = false f.flock(File::LOCK_UN) end end else # Just call up the middleware because we already hold the lock @app.call(env) end end |