module Misc def self.use_lock_id=(use = true) if use Log.medium "Activating lockfile ids" Lockfile.dont_use_lock_id = false Lockfile.refresh = 20 Lockfile.max_age = 60 * 10 Lockfile.suspend = 10 else Log.medium "De-activating lockfile ids" Lockfile.dont_use_lock_id = true Lockfile.refresh = 5 Lockfile.max_age = 30 Lockfile.suspend = 5 end Lockfile.refresh = 3 Lockfile.max_age = 10 Lockfile.suspend = 2 end self.use_lock_id = ENV["RBBT_NO_LOCKFILE_ID"] != "true" LOCK_MUTEX = Mutex.new #def self.lock(file, unlock = true, options = {}) def self.lock(file, unlock = true, options = {}) unlock, options = true, unlock if Hash === unlock return yield if file.nil? FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exists? File.dirname(File.expand_path(file)) res = nil case options[:lock] when Lockfile lockfile = options[:lock] lockfile.lock unless lockfile.locked? when FalseClass unlock = false else lock_path = File.expand_path(file + '.lock') lockfile = Lockfile.new(lock_path, options) lockfile.lock end begin res = yield lockfile rescue KeepLocked unlock = false res = $!.payload ensure if unlock begin lockfile.unlock #if lockfile.locked? rescue Exception end end end res end LOCK_REPO_SERIALIZER=Marshal def self.lock_in_repo(repo, key, *args) return yield file, *args if repo.nil? or key.nil? lock_key = "lock-" << key begin if repo[lock_key] and Misc.hostname == (info = LOCK_REPO_SERIALIZER.load(repo[lock_key]))["host"] and info["pid"] and not Misc.pid_exists?(info["pid"]) Log.info("Removing lockfile: #{lock_key}. This pid #{Process.pid}. Content: #{info.inspect}") repo.out lock_key end rescue Log.warn("Error checking lockfile #{lock_key}: #{$!.message}. Removing. Content: #{begin repo[lock_key] rescue "Could not open file" end}") repo.out lock_key if repo.include? lock_key end while repo[lock_key] sleep 1 end repo[lock_key] = LOCK_REPO_SERIALIZER.dump({:hostname => Misc.hostname, :pid => Process.pid}) res = yield lock_key, *args repo.delete lock_key res end end