summaryrefslogtreecommitdiff
path: root/lib/chef/run_lock.rb
diff options
context:
space:
mode:
authorClaire McQuin <claire@getchef.com>2014-05-01 14:38:07 -0700
committerClaire McQuin <claire@getchef.com>2014-05-05 09:25:05 -0700
commita20d6162f11154f248503f4145afff3a511afc98 (patch)
treeec4e924cdbd12b9014bddb4fa9261a7d6a44a3f5 /lib/chef/run_lock.rb
parent561b564d28e12731434513f1783cd519690e144b (diff)
downloadchef-a20d6162f11154f248503f4145afff3a511afc98.tar.gz
add option to abandon chef run if blocked by another for too long
Diffstat (limited to 'lib/chef/run_lock.rb')
-rw-r--r--lib/chef/run_lock.rb44
1 files changed, 40 insertions, 4 deletions
diff --git a/lib/chef/run_lock.rb b/lib/chef/run_lock.rb
index 972db1a4e1..68f697bb2b 100644
--- a/lib/chef/run_lock.rb
+++ b/lib/chef/run_lock.rb
@@ -20,6 +20,9 @@ require 'fcntl'
if Chef::Platform.windows?
require 'chef/win32/mutex'
end
+require 'chef/config'
+require 'chef/exceptions'
+require 'timeout'
class Chef
@@ -46,7 +49,9 @@ class Chef
end
# Acquire the system-wide lock. Will block indefinitely if another process
- # already has the lock.
+ # already has the lock and Chef::Config[:run_lock_timeout] is
+ # not set. Otherwise will block for Chef::Config[:run_lock_timeout]
+ # seconds and exit if the lock is not acquired.
#
# Each call to acquire should have a corresponding call to #release.
#
@@ -55,7 +60,23 @@ class Chef
# Either acquire() or test() methods should be called in order to
# get the ownership of run_lock.
def acquire
- wait unless test
+ if timeout_given?
+ begin
+ Timeout::timeout(time_to_wait) do
+ unless test
+ if time_to_wait > 0.0
+ wait
+ else
+ exit_from_timeout
+ end
+ end
+ end
+ rescue Timeout::Error => e
+ exit_from_timeout
+ end
+ else
+ wait unless test
+ end
end
#
@@ -92,7 +113,6 @@ class Chef
# Waits until acquiring the system-wide lock.
#
def wait
- runpid = runlock.read.strip.chomp
Chef::Log.warn("Chef client #{runpid} is running, will wait for it to finish and then run.")
if Chef::Platform.windows?
mutex.wait
@@ -144,6 +164,22 @@ class Chef
@mutex = Chef::ReservedNames::Win32::Mutex.new("Global\\#{runlock_file.gsub(/[\\]/, "/").downcase}")
mutex.test
end
+
+ def runpid
+ runlock.read.strip
+ end
+
+ def timeout_given?
+ !time_to_wait.nil?
+ end
+
+ def time_to_wait
+ Chef::Config[:run_lock_timeout]
+ end
+
+ def exit_from_timeout
+ release # Just to be on the safe side...
+ raise Chef::Exceptions::RunLockTimeout.new(time_to_wait, runpid)
+ end
end
end
-