class Mimi::DB::Lock::PostgresqlLock
Attributes
name[R]
name_uint64[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/postgresql_lock.rb, line 13 def initialize(name, opts = {}) @name = name @name_uint64 = Digest::SHA1.digest(name).unpack('q').first @options = opts @timeout = if opts[:timeout].nil? 0 elsif opts[:timeout] <= 0 :nowait else opts[:timeout] end end
Public Instance Methods
execute() { || ... }
click to toggle source
# File lib/mimi/db/lock/postgresql_lock.rb, line 27 def execute(&_block) ActiveRecord::Base.transaction(requires_new: true) do acquire_lock_with_timeout! yield if block_given? end end
Private Instance Methods
acquire_lock_with_timeout!()
click to toggle source
# File lib/mimi/db/lock/postgresql_lock.rb, line 60 def acquire_lock_with_timeout! unless timeout == :nowait old_timeout = lock_timeout self.lock_timeout = timeout unless timeout == old_timeout end if timeout == :nowait result = Mimi::DB.execute('select pg_try_advisory_xact_lock(?) as lock_acquired', name_uint64) lock_acquired = result.first['lock_acquired'] == 't' raise Mimi::DB::Lock::NotAvailable unless lock_acquired else begin Mimi::DB.execute('select pg_advisory_xact_lock(?)', name_uint64) rescue ActiveRecord::StatementInvalid raise Mimi::DB::Lock::NotAvailable end # NOTE: in case of a timeout the lock_timeout value will not be set back manually # .. it is expected to roll back with the transaction self.lock_timeout = old_timeout unless timeout == old_timeout end true end
lock_timeout()
click to toggle source
Returns current database connection setting for the lock timeout. Value of 0 means the lock timeout is not set.
@return [Float] Lock
timeout in seconds
# File lib/mimi/db/lock/postgresql_lock.rb, line 41 def lock_timeout result = Mimi::DB.execute('select setting from pg_settings where name = ?', :lock_timeout) value = result.first['setting'].to_i value = value.to_f / 1000 unless value == 0 value end
lock_timeout=(value)
click to toggle source
Sets the current database connection setting for the lock timeout. Value of 0 means the lock operations should never timeout.
@param [Float,Fixnum] value Lock
timeout in seconds
# File lib/mimi/db/lock/postgresql_lock.rb, line 53 def lock_timeout=(value) raise ArgumentError, 'Numeric value expected as timeout' unless value.is_a?(Numeric) value = (value * 1000).to_i Mimi::DB.execute('update pg_settings set setting = ? where name = ?', value, :lock_timeout) end