class ProcessLock

Constants

VERSION

Attributes

filename[R]

Public Class Methods

new(filename) click to toggle source
# File lib/process_lock.rb, line 14
def initialize(filename)
  @filename = filename
  if defined?(Rails) and Rails.root and (File.basename(filename) == @filename)
    @filename = File.join(Rails.root, 'tmp', 'pids', filename)
    unless filename =~ /\./
      @filename << '.pid'
    end
  end
  FileUtils.touch(@filename)
end

Public Instance Methods

acquire() { || ... } click to toggle source
# File lib/process_lock.rb, line 38
def acquire
  result = acquire_without_block
  if result and block_given?
    begin
      result = yield
    ensure
      release
    end
  end
  result
end
acquire!() { || ... } click to toggle source
# File lib/process_lock.rb, line 25
def acquire!
  result = acquired = acquire_without_block
  if acquired and block_given?
    begin
      result = yield
    ensure
      release
    end
  end
  raise(AlreadyLocked.new('Unable to acquire lock')) unless acquired
  result
end
alive?() click to toggle source
# File lib/process_lock.rb, line 68
def alive?
  pid = read
  return pid > 0 ? Process.kill(0, pid) > 0 : false
rescue
  return false
end
owner?() click to toggle source
# File lib/process_lock.rb, line 75
def owner?
  pid = read
  pid and pid > 0 and pid == Process.pid
end
read() click to toggle source
# File lib/process_lock.rb, line 80
def read
  open_and_lock{|f| f.read.to_i}
end
release() click to toggle source
# File lib/process_lock.rb, line 57
def release
  acquired = false
  open_and_lock do |f|
    acquired = owner?
    if acquired
      f.truncate(f.write(''))
    end
  end
  acquired
end
release!() click to toggle source
# File lib/process_lock.rb, line 50
def release!
  unless release
    raise NotLocked.new('Unable to release lock (probably did not own it)')
  end
  true
end

Private Instance Methods

acquire_without_block() click to toggle source
# File lib/process_lock.rb, line 86
def acquire_without_block
  result = false
  open_and_lock do |f|
    result = owner? || ! alive?
    if result
      f.rewind
      f.truncate(f.write(Process.pid))
    end
  end
  result
end
lock(file, blocking = true) { || ... } click to toggle source
# File lib/process_lock.rb, line 115
def lock(file, blocking = true)
  file.flock(blocking ? File::LOCK_EX : File::LOCK_EX | File::LOCK_NB)
  return yield
ensure
  file.flock(File::LOCK_UN)
end
open_and_lock() { |locked_file| ... } click to toggle source
# File lib/process_lock.rb, line 98
def open_and_lock
  old_locked_file = @locked_file
  if @locked_file
    @locked_file.rewind
    return yield @locked_file
  else
    File.open(@filename, 'r+') do |f|
      lock(f) do
        @locked_file = f
        return yield f
      end
    end
  end
ensure
  @locked_file = old_locked_file
end