Class: ActiveRecord::DatabaseMutex::Implementation
- Inherits:
-
Object
- Object
- ActiveRecord::DatabaseMutex::Implementation
- Defined in:
- lib/active_record/database_mutex/implementation.rb
Class Attribute Summary collapse
-
.table_name ⇒ Object
Returns the value of attribute table_name.
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.
- #table_name ⇒ Object
-
#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.
14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/active_record/database_mutex/implementation.rb', line 14 def initialize(opts = {}) @name = opts[:name] or raise ArgumentError, "mutex requires a :name argument" query %{ CREATE TABLE IF NOT EXISTS #{table_name} ( name CHAR(255) NOT NULL, counter INT UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY (name(128)) ) DEFAULT CHARSET=utf8mb4 } end |
Class Attribute Details
.table_name ⇒ Object
Returns the value of attribute table_name.
9 10 11 |
# File 'lib/active_record/database_mutex/implementation.rb', line 9 def table_name @table_name end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the name of this mutex as given as a constructor argument.
35 36 37 |
# File 'lib/active_record/database_mutex/implementation.rb', line 35 def name @name end |
Instance Method Details
#aquired_lock? ⇒ Boolean
Returns true if this mutex is locked by this database connection.
121 122 123 |
# File 'lib/active_record/database_mutex/implementation.rb', line 121 def aquired_lock? query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{quote(name)})") == 1 end |
#db ⇒ Object
30 31 32 |
# File 'lib/active_record/database_mutex/implementation.rb', line 30 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.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/active_record/database_mutex/implementation.rb', line 65 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.
116 117 118 |
# File 'lib/active_record/database_mutex/implementation.rb', line 116 def locked? not unlocked? end |
#not_aquired_lock? ⇒ Boolean
Returns true if this mutex is not locked by this database connection.
126 127 128 |
# File 'lib/active_record/database_mutex/implementation.rb', line 126 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.
51 52 53 54 55 56 57 58 |
# File 'lib/active_record/database_mutex/implementation.rb', line 51 def synchronize(opts = {}) locked = lock(opts) or return yield rescue ActiveRecord::DatabaseMutex::MutexLocked return nil ensure locked and unlock end |
#table_name ⇒ Object
26 27 28 |
# File 'lib/active_record/database_mutex/implementation.rb', line 26 def table_name self.class.table_name end |
#to_s ⇒ Object Also known as: inspect
Returns a string representation of this DatabaseMutex instance.
131 132 133 |
# File 'lib/active_record/database_mutex/implementation.rb', line 131 def to_s "#<#{self.class} #{name}>" end |
#unlock ⇒ Object
Unlocks the mutex and returns true if successful. Otherwise this method raises a MutexLocked exception.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/active_record/database_mutex/implementation.rb', line 85 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.
103 104 105 106 107 108 |
# File 'lib/active_record/database_mutex/implementation.rb', line 103 def unlock?(*a) unlock(*a) self rescue MutexUnlockFailed nil end |
#unlocked? ⇒ Boolean
Returns true if this mutex is unlocked at the moment.
111 112 113 |
# File 'lib/active_record/database_mutex/implementation.rb', line 111 def unlocked? query(%{ SELECT IS_FREE_LOCK(#{quote(name)}) }).to_i == 1 end |