Sha256: 89087a9b028f7a8108407ef50d0b688421384191c3e019923126cc027485bdcb

Contents?: true

Size: 917 Bytes

Versions: 3

Compression:

Stored size: 917 Bytes

Contents

require 'digest'

class TN::AdvisoryLock
  def initialize(key, wait: false)
    key = self.class.string_to_int(key) unless key.is_a?(Integer)
    @key  = key
    @wait = wait
  end

  # Convert a string to a int that's needed for the advisory lock.
  def self.string_to_int(string)
    Digest::SHA1.hexdigest(string)[0..10].to_i(36)
  end

  def self.with_lock(key, wait: false)
    result = nil
    new(key, wait: wait).exclusive do
      result = yield
    end
    result
  end

  def exclusive
    if acquired?
      begin
        yield
      ensure
        release!
      end
    else
      return false
    end
    true
  end

private

  def acquired?
    TN.execute_sql("select #{sql_function}(#{@key})") != "f"
  end

  def sql_function
    if @wait
      "pg_advisory_lock"
    else
      "pg_try_advisory_lock"
    end
  end

  def release!
    TN.execute_sql("select pg_advisory_unlock(#{@key})")
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
dino_utils-0.1.12 lib/tn/advisory_lock.rb
dino_utils-0.1.11 lib/tn/advisory_lock.rb
dino_utils-0.1.10 lib/tn/advisory_lock.rb