Module: ZK::Mongoid::Locking
- Defined in:
- lib/zk/mongoid.rb
Overview
provides a lock_for_update method based on the current class name and Mongoid document _id.
Before use (in one of your Rails initializers, for example) you should assign either a ZK::Client or ZK::Pool subclass to ZK::Mongoid::Locking.zk_lock_pool.
this class assumes the availability of a 'logger' method in the mixee
Constant Summary collapse
- VALID_MODES =
[:exclusive, :shared].freeze
- @@zk_lock_pool =
nil
Class Method Summary collapse
Instance Method Summary collapse
-
#assert_locked_for_share!(name = nil) ⇒ Object
raises MustBeShareLockedException if we're not currently inside a shared lock (optionally with
name). -
#assert_locked_for_update!(name = nil) ⇒ Object
raises MustBeExclusivelyLockedException if we're not currently inside a lock (optionally with
name). -
#lock_for_update(name = nil) ⇒ Object
(also: #with_exclusive_lock)
Provides a re-entrant zookeeper-based lock of a record.
-
#locked_for_share?(name = nil) ⇒ Boolean
:nodoc:.
-
#locked_for_update?(name = nil) ⇒ Boolean
:nodoc:.
- #with_shared_lock(name = nil) ⇒ Object
-
#zk_lock_name(name = nil) ⇒ Object
:nodoc:.
Class Method Details
.zk_lock_pool ⇒ Object
17 18 19 |
# File 'lib/zk/mongoid.rb', line 17 def self.zk_lock_pool @@zk_lock_pool end |
.zk_lock_pool=(pool) ⇒ Object
21 22 23 |
# File 'lib/zk/mongoid.rb', line 21 def self.zk_lock_pool=(pool) @@zk_lock_pool = pool end |
Instance Method Details
#assert_locked_for_share!(name = nil) ⇒ Object
raises MustBeShareLockedException if we're not currently inside a shared lock
(optionally with name)
100 101 102 |
# File 'lib/zk/mongoid.rb', line 100 def assert_locked_for_share!(name=nil) raise ZK::Exceptions::MustBeShareLockedException unless locked_for_share?(name) end |
#assert_locked_for_update!(name = nil) ⇒ Object
raises MustBeExclusivelyLockedException if we're not currently inside a
lock (optionally with name)
94 95 96 |
# File 'lib/zk/mongoid.rb', line 94 def assert_locked_for_update!(name=nil) raise ZK::Exceptions::MustBeExclusivelyLockedException unless locked_for_update?(name) end |
#lock_for_update(name = nil) ⇒ Object Also known as: with_exclusive_lock
Provides a re-entrant zookeeper-based lock of a record.
This also makes it possible to detect if the record has been locked before performing a potentially dangerous operation by using the assert_locked_for_update! instance method
Locks are re-entrant per-thread, but will work as a mutex between threads.
You can optionally provide a 'name' which will act as a sub-lock of
sorts. For example, if you are going to create an embedded document,
and only want one process to be able to create it at a time (without
clobbering one another), but don't want to lock the entire record, you
can specify a name for the lock, that way the same code running
elsewhere will synchronize based on the parent record and the
particular action specified by name.
Example
use of "name"
class Thing
include Mongoid::Document
include ZK::Mongoid::Locking
:parent, :inverse_of => :thing
end
class Parent
include Mongoid::Document
include ZK::Mongoid::Locking
:thing
def lets_create_a_thing
lock_for_update('thing_creation') do
raise "We already got one! it's very nice!" if thing
do_something_that_might_take_a_while
create_thing
end
end
end
Now, while the creation of the Thing is synchronized, other processes can update other aspects of Parent.
74 75 76 77 78 79 80 81 |
# File 'lib/zk/mongoid.rb', line 74 def lock_for_update(name=nil) if locked_for_update?(name) logger.debug { "we are locked for update, yield to the block" } yield else zk_with_lock(:mode => :exclusive, :name => name) { yield } end end |
#locked_for_share?(name = nil) ⇒ Boolean
:nodoc:
108 109 110 |
# File 'lib/zk/mongoid.rb', line 108 def locked_for_share?(name=nil) #:nodoc: zk_mongoid_lock_registry[:shared].include?(zk_lock_name(name)) end |
#locked_for_update?(name = nil) ⇒ Boolean
:nodoc:
104 105 106 |
# File 'lib/zk/mongoid.rb', line 104 def locked_for_update?(name=nil) #:nodoc: zk_mongoid_lock_registry[:exclusive].include?(zk_lock_name(name)) end |
#with_shared_lock(name = nil) ⇒ Object
84 85 86 87 88 89 90 |
# File 'lib/zk/mongoid.rb', line 84 def with_shared_lock(name=nil) if locked_for_share?(name) yield else zk_with_lock(:mode => :shared, :name => name) { yield } end end |
#zk_lock_name(name = nil) ⇒ Object
:nodoc:
112 113 114 |
# File 'lib/zk/mongoid.rb', line 112 def zk_lock_name(name=nil) #:nodoc: [self.class.to_s, self.id.to_s, name].compact.join('-') end |