Class: Locker::Advisory
- Inherits:
-
Object
- Object
- Locker::Advisory
- Defined in:
- lib/locker/advisory.rb
Defined Under Namespace
Classes: LockConnectionLost
Constant Summary collapse
- MAX_LOCK =
2147483647
- MIN_LOCK =
-2147483648
- OVERFLOW_ADJUSTMENT =
2**32
Instance Attribute Summary collapse
-
#blocking ⇒ Object
readonly
Returns the value of attribute blocking.
-
#crc ⇒ Object
readonly
Returns the value of attribute crc.
-
#key ⇒ Object
readonly
Returns the value of attribute key.
-
#locked ⇒ Object
readonly
Returns the value of attribute locked.
-
#lockspace ⇒ Object
readonly
Returns the value of attribute lockspace.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(key, options = {}) ⇒ Advisory
constructor
A new instance of Advisory.
- #run(&block) ⇒ Object
Constructor Details
#initialize(key, options = {}) ⇒ Advisory
Returns a new instance of Advisory.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/locker/advisory.rb', line 13 def initialize(key, ={}) raise ArgumentError, "key must be a string" unless key.is_a?(String) @key = key @crc = convert_to_crc(key) @lockspace = ([:lockspace] || 1) @blocking = !![:blocking] @locked = false @block_timeout = [:block_timeout] @block_spin_wait = [:block_spin_wait] || 0.005 if !@lockspace.is_a?(Integer) || @lockspace < MIN_LOCK || @lockspace > MAX_LOCK raise ArgumentError, "The :lockspace option must be an integer between #{MIN_LOCK} and #{MAX_LOCK}" end end |
Instance Attribute Details
#blocking ⇒ Object (readonly)
Returns the value of attribute blocking.
7 8 9 |
# File 'lib/locker/advisory.rb', line 7 def blocking @blocking end |
#crc ⇒ Object (readonly)
Returns the value of attribute crc.
7 8 9 |
# File 'lib/locker/advisory.rb', line 7 def crc @crc end |
#key ⇒ Object (readonly)
Returns the value of attribute key.
7 8 9 |
# File 'lib/locker/advisory.rb', line 7 def key @key end |
#locked ⇒ Object (readonly)
Returns the value of attribute locked.
7 8 9 |
# File 'lib/locker/advisory.rb', line 7 def locked @locked end |
#lockspace ⇒ Object (readonly)
Returns the value of attribute lockspace.
7 8 9 |
# File 'lib/locker/advisory.rb', line 7 def lockspace @lockspace end |
Class Method Details
.run(key, options = {}, &block) ⇒ Object
29 30 31 32 |
# File 'lib/locker/advisory.rb', line 29 def self.run(key, ={}, &block) advisory = new(key, ) advisory.run(&block) end |
Instance Method Details
#run(&block) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/locker/advisory.rb', line 34 def run(&block) connection = ActiveRecord::Base.connection_pool.checkout connection.transaction :requires_new => true do if @blocking && @block_timeout break_at = Time.now + @block_timeout end while !get(connection) && @blocking break if break_at && break_at < Time.now sleep @block_spin_wait end if @locked begin parent_thread = Thread.current mutex = Mutex.new checker = Thread.new do while @locked 10.times{ sleep 0.5 if @locked } mutex.synchronize do if @locked check(connection, parent_thread) end end end end block.call ensure @locked = false # Using a mutex to synchronize so that we're sure we're not # executing a query when we kill the thread. mutex.synchronize do if checker.alive? checker.exit rescue nil end end end true else false end end ensure ActiveRecord::Base.connection_pool.checkin(connection) if connection end |