Class: ActiveRecord::DatabaseMutex::Implementation
- Inherits:
-
Object
- Object
- ActiveRecord::DatabaseMutex::Implementation
- Defined in:
- lib/active_record/database_mutex/implementation.rb
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the name of this mutex as given as a constructor argument.
Instance Method Summary collapse
-
#aquired_lock? ⇒ Boolean
Returns true if this mutex is locked by this database connection.
- #db ⇒ Object
-
#initialize(opts = {}) ⇒ Implementation
constructor
Creates a mutex with the name given with the option :name.
-
#lock(opts = {}) ⇒ Object
Locks the mutex and returns true if successful.
-
#locked? ⇒ Boolean
Returns true if this mutex is locked at the moment.
-
#not_aquired_lock? ⇒ Boolean
Returns true if this mutex is not locked by this database connection.
-
#synchronize(opts = {}) ⇒ Object
Locks the mutex if it isn’t already locked via another database connection and yields to the given block.
-
#to_s ⇒ Object
(also: #inspect)
Returns a string representation of this DatabaseMutex instance.
-
#unlock ⇒ Object
Unlocks the mutex and returns true if successful.
-
#unlock?(*a) ⇒ Boolean
Unlock this mutex and return self if successful, otherwise (the mutex was not locked) nil is returned.
-
#unlocked? ⇒ Boolean
Returns true if this mutex is unlocked at the moment.
Constructor Details
#initialize(opts = {}) ⇒ Implementation
Creates a mutex with the name given with the option :name.
9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/active_record/database_mutex/implementation.rb', line 9 def initialize(opts = {}) @name = opts[:name] or raise ArgumentError, "mutex requires a :name argument" query %{ CREATE TEMPORARY TABLE IF NOT EXISTS mutex_counters ( name CHAR(255) NOT NULL, counter INT UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY (name) ) DEFAULT CHARSET=utf8mb4 } end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the name of this mutex as given as a constructor argument.
26 27 28 |
# File 'lib/active_record/database_mutex/implementation.rb', line 26 def name @name end |
Instance Method Details
#aquired_lock? ⇒ Boolean
Returns true if this mutex is locked by this database connection.
112 113 114 |
# File 'lib/active_record/database_mutex/implementation.rb', line 112 def aquired_lock? query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{quote(name)})") == 1 end |
#db ⇒ Object
21 22 23 |
# File 'lib/active_record/database_mutex/implementation.rb', line 21 def db ActiveRecord::Base.connection 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.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/active_record/database_mutex/implementation.rb', line 56 def lock(opts = {}) if opts[:nonblock] # XXX document begin lock_with_timeout :timeout => 0 rescue MutexLocked end elsif opts[:timeout] lock_with_timeout opts else spin_timeout = opts[:spin_timeout] || 1 # XXX document begin lock_with_timeout :timeout => spin_timeout rescue MutexLocked retry end end end |
#locked? ⇒ Boolean
Returns true if this mutex is locked at the moment.
107 108 109 |
# File 'lib/active_record/database_mutex/implementation.rb', line 107 def locked? not unlocked? end |
#not_aquired_lock? ⇒ Boolean
Returns true if this mutex is not locked by this database connection.
117 118 119 |
# File 'lib/active_record/database_mutex/implementation.rb', line 117 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.
42 43 44 45 46 47 48 49 |
# File 'lib/active_record/database_mutex/implementation.rb', line 42 def synchronize(opts = {}) locked = lock(opts) or return yield rescue ActiveRecord::DatabaseMutex::MutexLocked return nil ensure locked and unlock end |
#to_s ⇒ Object Also known as: inspect
Returns a string representation of this DatabaseMutex instance.
122 123 124 |
# File 'lib/active_record/database_mutex/implementation.rb', line 122 def to_s "#<#{self.class} #{name}>" end |
#unlock ⇒ Object
Unlocks the mutex and returns true if successful. Otherwise this method raises a MutexLocked exception.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/active_record/database_mutex/implementation.rb', line 76 def unlock(*) if aquired_lock? decrease_counter if counter_zero? case query %{ SELECT RELEASE_LOCK(#{quote(name)}) } when 1 true when 0, nil raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed" end end else raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed" end end |
#unlock?(*a) ⇒ Boolean
Unlock this mutex and return self if successful, otherwise (the mutex was not locked) nil is returned.
94 95 96 97 98 99 |
# File 'lib/active_record/database_mutex/implementation.rb', line 94 def unlock?(*a) unlock(*a) self rescue MutexUnlockFailed nil end |
#unlocked? ⇒ Boolean
Returns true if this mutex is unlocked at the moment.
102 103 104 |
# File 'lib/active_record/database_mutex/implementation.rb', line 102 def unlocked? query(%{ SELECT IS_FREE_LOCK(#{quote(name)}) }).to_i == 1 end |