module Bricolage::VacuumLock

Constants

DEFAULT_VACUUM_LOCK_FILE
DEFAULT_VACUUM_LOCK_TIMEOUT

Public Class Methods

cleanup_vacuum_lock() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 89
def VacuumLock.cleanup_vacuum_lock
  return unless enable_vacuum_lock?
  path, timeout = vacuum_lock_parameters
  if locking?(path)
    $stderr.puts "remove VACUUM lock by #{Process.pid}"
    FileUtils.rm_f path
  end
end
create_lockfile_cmd() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 43
def create_lockfile_cmd
  Pathname(__FILE__).parent.parent.parent + 'libexec/create-lockfile'
end
create_vacuum_lock_file(path, timeout) click to toggle source
# File lib/bricolage/vacuumlock.rb, line 60
def create_vacuum_lock_file(path, timeout)
  start_time = Time.now
  begin
    File.open(path, File::WRONLY | File::CREAT | File::EXCL) {|f|
      f.puts "#{Time.now}: created by bricolage [#{Process.pid}]"
    }
  rescue Errno::EEXIST
    if Time.now - start_time > timeout
      raise LockTimeout, "could not create lock file: #{path} (timeout #{timeout} seconds)"
    end
    sleep 1
    retry
  end
end
enable_vacuum_lock?() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 7
def enable_vacuum_lock?
  !!ENV['BRICOLAGE_VACUUM_LOCK']
end
locking?(path) click to toggle source
# File lib/bricolage/vacuumlock.rb, line 98
def VacuumLock.locking?(path)
  # do not check file existance, just read to avoid race condition
  locker_pid = File.read(path).slice(/\[(\d+)\]/, 1).to_i
  $stderr.puts "bricolage_pid: #{$$}, vacuum_locked_by: #{locker_pid}"
  locker_pid == Process.pid
rescue
  $stderr.puts "bricolage_pid: #{$$}, vacuum_locked_by: (none)"
  false
end
psql_serialize_vacuum_begin() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 23
def psql_serialize_vacuum_begin
  if enable_vacuum_lock?
    path, timeout = vacuum_lock_parameters
    "\\! #{create_lockfile_cmd} #{path} #{timeout}"
  else
    ';'
  end
end
psql_serialize_vacuum_end() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 33
def psql_serialize_vacuum_end
  if enable_vacuum_lock?
    path, timeout = vacuum_lock_parameters
    "\\! rm -f #{path}"
  else
    ';'
  end
end
serialize_vacuum() { || ... } click to toggle source
# File lib/bricolage/vacuumlock.rb, line 48
def serialize_vacuum
  return yield unless enable_vacuum_lock?
  path, timeout = vacuum_lock_parameters
  create_vacuum_lock_file path, timeout
  begin
    yield
  ensure
    FileUtils.rm_f path
  end
end
using() { || ... } click to toggle source
# File lib/bricolage/vacuumlock.rb, line 76
def VacuumLock.using
  return yield unless enable_vacuum_lock?
  begin
    yield
  ensure
    cleanup_vacuum_lock
  end
end
vacuum_lock_parameters() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 15
def vacuum_lock_parameters
  return nil unless enable_vacuum_lock?
  path, tm = ENV['BRICOLAGE_VACUUM_LOCK'].split(':', 2)
  timeout = tm ? [tm.to_i, 1].max : DEFAULT_VACUUM_LOCK_TIMEOUT
  return path, timeout
end

Public Instance Methods

using_vacuum_lock(&block) click to toggle source
# File lib/bricolage/vacuumlock.rb, line 85
def using_vacuum_lock(&block)
  VacuumLock.using(&block)
end

Private Instance Methods

create_lockfile_cmd() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 43
def create_lockfile_cmd
  Pathname(__FILE__).parent.parent.parent + 'libexec/create-lockfile'
end
create_vacuum_lock_file(path, timeout) click to toggle source
# File lib/bricolage/vacuumlock.rb, line 60
def create_vacuum_lock_file(path, timeout)
  start_time = Time.now
  begin
    File.open(path, File::WRONLY | File::CREAT | File::EXCL) {|f|
      f.puts "#{Time.now}: created by bricolage [#{Process.pid}]"
    }
  rescue Errno::EEXIST
    if Time.now - start_time > timeout
      raise LockTimeout, "could not create lock file: #{path} (timeout #{timeout} seconds)"
    end
    sleep 1
    retry
  end
end
enable_vacuum_lock?() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 7
def enable_vacuum_lock?
  !!ENV['BRICOLAGE_VACUUM_LOCK']
end
psql_serialize_vacuum_begin() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 23
def psql_serialize_vacuum_begin
  if enable_vacuum_lock?
    path, timeout = vacuum_lock_parameters
    "\\! #{create_lockfile_cmd} #{path} #{timeout}"
  else
    ';'
  end
end
psql_serialize_vacuum_end() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 33
def psql_serialize_vacuum_end
  if enable_vacuum_lock?
    path, timeout = vacuum_lock_parameters
    "\\! rm -f #{path}"
  else
    ';'
  end
end
serialize_vacuum() { || ... } click to toggle source
# File lib/bricolage/vacuumlock.rb, line 48
def serialize_vacuum
  return yield unless enable_vacuum_lock?
  path, timeout = vacuum_lock_parameters
  create_vacuum_lock_file path, timeout
  begin
    yield
  ensure
    FileUtils.rm_f path
  end
end
vacuum_lock_parameters() click to toggle source
# File lib/bricolage/vacuumlock.rb, line 15
def vacuum_lock_parameters
  return nil unless enable_vacuum_lock?
  path, tm = ENV['BRICOLAGE_VACUUM_LOCK'].split(':', 2)
  timeout = tm ? [tm.to_i, 1].max : DEFAULT_VACUUM_LOCK_TIMEOUT
  return path, timeout
end