class Mimi::DB::Lock::SqliteLock

Attributes

lock_filename[R]
name[R]
name_digest[R]
options[R]
timeout[R]

Public Class Methods

new(name, opts = {}) click to toggle source

Timeout semantics: nil – wait indefinitely 0 – do not wait <s> – wait <s> seconds (can be Float)

# File lib/mimi/db/lock/sqlite_lock.rb, line 13
def initialize(name, opts = {})
  @name = name
  @name_digest = Digest::SHA1.hexdigest(name).first(16)
  @options = opts
  @timeout =
    if opts[:timeout].nil?
      -1
    elsif opts[:timeout] <= 0
      0.100
    else
      opts[:timeout].to_f.round
    end
  db_filename = Pathname.new(Mimi::DB.module_options[:db_database]).expand_path
  @lock_filename = "#{db_filename}.lock-#{name_digest}"
  @lock_acquired = nil
  @file = nil
end

Public Instance Methods

execute() { || ... } click to toggle source
# File lib/mimi/db/lock/sqlite_lock.rb, line 31
def execute(&_block)
  ActiveRecord::Base.transaction(requires_new: true) do
    begin
      acquire_lock_with_timeout!
      yield if block_given?
    ensure
      release_lock!
    end
  end
end

Private Instance Methods

acquire_lock_with_timeout!() click to toggle source
# File lib/mimi/db/lock/sqlite_lock.rb, line 45
def acquire_lock_with_timeout!
  @file = File.open(lock_filename, File::RDWR | File::CREAT, 0644)
  if timeout
    Timeout.timeout(timeout, Mimi::DB::Lock::NotAvailable) { @file.flock(File::LOCK_EX) }
  else
    @file.flock(File::LOCK_EX)
  end
  @lock_acquired = true
  true
end
release_lock!() click to toggle source
# File lib/mimi/db/lock/sqlite_lock.rb, line 57
def release_lock!
  @file.flock(File::LOCK_UN) if @lock_acquired
  @file.close
  # NOTE: do not unlink file here, it leads to a potential race condition:
  # http://world.std.com/~swmcd/steven/tech/flock.html
  true
end