class Travis::Lock::Postgresql

Public Class Methods

new(*) click to toggle source
Calls superclass method
# File lib/travis/lock/postgresql.rb, line 17
def initialize(*)
  super
  fail 'lock name cannot be blank' if name.nil? || name.empty?
end

Public Instance Methods

exclusive(&block) click to toggle source
# File lib/travis/lock/postgresql.rb, line 22
def exclusive(&block)
  with_timeout { obtain_lock }
  transactional? ? connection.transaction(&block) : with_release(&block)
end

Private Instance Methods

connection() click to toggle source
# File lib/travis/lock/postgresql.rb, line 71
def connection
  ActiveRecord::Base.connection
end
key() click to toggle source
# File lib/travis/lock/postgresql.rb, line 75
def key
  Zlib.crc32(name).to_i & 0x7fffffff
end
obtain_lock() click to toggle source
# File lib/travis/lock/postgresql.rb, line 33
def obtain_lock
  result = connection.select_value("select #{pg_function}(#{key});")
  try? ? result == 't' : true
end
pg_function() click to toggle source
# File lib/travis/lock/postgresql.rb, line 64
def pg_function
  func = ['pg', 'advisory', 'lock']
  func.insert(2, 'xact') if transactional?
  func.insert(1, 'try')  if try?
  func.join('_')
end
timeout() click to toggle source
# File lib/travis/lock/postgresql.rb, line 48
def timeout
  options[:timeout] || 30
end
transactional?() click to toggle source
# File lib/travis/lock/postgresql.rb, line 52
def transactional?
  !!options[:transactional]
end
try?() click to toggle source
# File lib/travis/lock/postgresql.rb, line 44
def try?
  !!options[:try]
end
with_release() { || ... } click to toggle source
# File lib/travis/lock/postgresql.rb, line 38
def with_release
  yield
ensure
  connection.execute("select pg_advisory_unlock(#{key});")
end
with_statement_timeout() { || ... } click to toggle source
# File lib/travis/lock/postgresql.rb, line 56
def with_statement_timeout
  connection.execute("set statement_timeout to #{Integer(timeout * 1000)};")
  yield
rescue ActiveRecord::StatementInvalid => e
  retry if defined?(PG) && e.original_exception.is_a?(PG::QueryCanceled)
  timeout!
end
with_timeout(&block) click to toggle source
# File lib/travis/lock/postgresql.rb, line 29
def with_timeout(&block)
  try? ? Retry.new(name, options).run(&block) : with_statement_timeout(&block)
end