Class: ActiveRecord::DatabaseMutex::Implementation

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/database_mutex/implementation.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Implementation

Creates a mutex with the name given with the option :name.



5
6
7
# File 'lib/active_record/database_mutex/implementation.rb', line 5

def initialize(opts = {})
  @name = opts[:name] or raise ArgumentError, "mutex requires a :name argument"
end

Instance Attribute Details

#nameObject (readonly)

Returns the name of this mutex as given as a constructor argument.



10
11
12
# File 'lib/active_record/database_mutex/implementation.rb', line 10

def name
  @name
end

Instance Method Details

#aquired_lock?Boolean

Returns true if this mutex is locked by this database connection.

Returns:

  • (Boolean)


73
74
75
# File 'lib/active_record/database_mutex/implementation.rb', line 73

def aquired_lock?
  query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{ActiveRecord::Base.quote_value(name)})") == 1
end

#lock(opts = {}) ⇒ Object

Locks the mutex and returns true if successful. If the mutex is already locked and the timeout in seconds is given as the :timeout option, this method raises a MutexLocked exception after that many seconds. If the :timeout option wasn’t given, this method blocks until the lock could be aquired.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/active_record/database_mutex/implementation.rb', line 41

def lock(opts = {})
  if opts[:timeout]
    lock_with_timeout opts
  else
    begin
      lock_with_timeout :timeout => 1
    rescue MutexLocked
      retry
    end
  end
end

#locked?Boolean

Returns true if this mutex is locked at the moment.

Returns:

  • (Boolean)


68
69
70
# File 'lib/active_record/database_mutex/implementation.rb', line 68

def locked?
  not unlocked?
end

#not_aquired_lock?Boolean

Returns true if this mutex is not locked by this database connection.

Returns:

  • (Boolean)


78
79
80
# File 'lib/active_record/database_mutex/implementation.rb', line 78

def not_aquired_lock?
  not aquired_lock?
end

#synchronize(opts = {}) ⇒ Object

Locks the mutex if it isn’t already locked via another database connection and yields to the given block. After executing the block’s content the mutex is unlocked (only if it was locked by this synchronize method before).

If the mutex was already locked by another database connection the method blocks until it could aquire the lock and only then the block’s content is executed. If the mutex was already locked by the current database connection then the block’s content is run and the the mutex isn’t unlocked afterwards.

If a value in seconds is passed to the :timeout option the blocking ends after that many seconds and the method returns immediately if the lock couldn’t be aquired during that time.



26
27
28
29
30
31
32
33
34
# File 'lib/active_record/database_mutex/implementation.rb', line 26

def synchronize(opts = {})
  locked_before = aquired_lock?
  lock opts
  yield
rescue ActiveRecord::DatabaseMutex::MutexLocked
  return nil
ensure
  locked_before or unlock
end

#to_sObject Also known as: inspect

Returns a string representation of this DatabaseMutex instance.



83
84
85
# File 'lib/active_record/database_mutex/implementation.rb', line 83

def to_s
  "#<#{self.class} #{name}>"
end

#unlockObject

Unlocks the mutex and returns true if successful. Otherwise this method raises a MutexLocked exception.



55
56
57
58
59
60
# File 'lib/active_record/database_mutex/implementation.rb', line 55

def unlock(*)
  case query("SELECT RELEASE_LOCK(#{ActiveRecord::Base.quote_value(name)})")
  when 1      then true
  when 0, nil then raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
  end
end

#unlocked?Boolean

Returns true if this mutex is unlocked at the moment.

Returns:

  • (Boolean)


63
64
65
# File 'lib/active_record/database_mutex/implementation.rb', line 63

def unlocked?
  query("SELECT IS_FREE_LOCK(#{ActiveRecord::Base.quote_value(name)})") == 1
end