Sha256: 44f260bc93fa62fe21ce7ad3914db63db7f1da4c70bb8e466edf5f81daee37df

Contents?: true

Size: 919 Bytes

Versions: 8

Compression:

Stored size: 919 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

8 entries across 8 versions & 1 rubygems

Version Path
dino_utils-0.1.21 lib/tn/advisory_lock.rb
dino_utils-0.1.20 lib/tn/advisory_lock.rb
dino_utils-0.1.19 lib/tn/advisory_lock.rb
dino_utils-0.1.18 lib/tn/advisory_lock.rb
dino_utils-0.1.16 lib/tn/advisory_lock.rb
dino_utils-0.1.15 lib/tn/advisory_lock.rb
dino_utils-0.1.14 lib/tn/advisory_lock.rb
dino_utils-0.1.13 lib/tn/advisory_lock.rb