Class | OpenWFE::StoreWithLocks |
In: |
lib/openwfe/worklist/storelocks.rb
|
Parent: | Object |
A wrapper for a Store[Participant] that includes a lock system.
DEFAULT_LOCK_MAX_AGE | = | "1h" |
lock_max_age | [RW] | |
store | [R] |
Builds a new store with a lock system wrapping a ‘real_store’.
This parameter ‘real_store’ may be a Class, like in
store = StoreWithLocks.new(HashParticipant)
You can retrieve the ‘real store’ with
real_store = store.store
By default, a lock is kept for one hour. You can change that value with, for example :
store = StoreWithLocks.new(HashParticipant, :lock_max_age => "30m10s"
(setting the lock maximum age to thirty minutes and 10 seconds).
# File lib/openwfe/worklist/storelocks.rb, line 82 82: def initialize (real_store, application_context=nil, params={}) 83: 84: @store = real_store 85: @store = @store.new if @store.kind_of?(Class) 86: 87: self.application_context = application_context 88: 89: @lock_max_age = params[:lock_max_age] || DEFAULT_LOCK_MAX_AGE 90: @lock_max_age = Rufus::parse_time_string @lock_max_age 91: 92: @locks = {} 93: @lock_mutex = Mutex.new 94: end
Sets the application context of this store lock and of the real store behind.
# File lib/openwfe/worklist/storelocks.rb, line 100 100: def application_context= (ac) 101: 102: @application_context = ac 103: 104: if @store.respond_to?(:application_context=) and \ 105: not store.application_context 106: 107: @store.application_context = @application_context 108: end 109: end
Iterates over the workitems in the store.
Doesn‘t care about any order for now.
# File lib/openwfe/worklist/storelocks.rb, line 213 213: def each (&block) # :yields: workitem, locked 214: 215: @store.each do |fei, workitem| 216: block.call workitem, locked?(fei) 217: end 218: end
Gets a workitem without locking it.
# File lib/openwfe/worklist/storelocks.rb, line 135 135: def get (key) 136: 137: @store[key] 138: end
Get a workitem, lock it and then return it. Ensures that no other ‘locker’ can lock it meanwhile.
# File lib/openwfe/worklist/storelocks.rb, line 115 115: def get_and_lock (locker, key) 116: 117: @lock_mutex.synchronize do 118: 119: object = @store[key] 120: 121: return nil unless object 122: 123: not_locked?(key) 124: 125: @locks[key] = [ locker, Time.now.to_i ] 126: object 127: end 128: end
Returns the locker currently holding a given object (known by its key). Will return nil if the object is not locked (or doesn‘t exist).
# File lib/openwfe/worklist/storelocks.rb, line 158 158: def get_locker (key) 159: 160: lock = get_lock key 161: return nil unless lock 162: lock[0] 163: end
Directly forwards the list_workitems() call to the wrapped store.
# File lib/openwfe/worklist/storelocks.rb, line 187 187: def list_workitems (workflow_instance_id=nil) 188: 189: @store.list_workitems(workflow_instance_id) 190: end
Removes a lock set on an item. If the item was locked by some other locker, will raise an exception. If the item was not locked, will simply exit silently.
# File lib/openwfe/worklist/storelocks.rb, line 145 145: def release (locker, key) 146: 147: @lock_mutex.synchronize do 148: holding_lock? locker, key 149: @locks.delete key 150: end 151: end
Returns the count of workitems in the store.
# File lib/openwfe/worklist/storelocks.rb, line 195 195: def size 196: 197: @store.size 198: end
Returns the lock info (else nil) for the given key.
# File lib/openwfe/worklist/storelocks.rb, line 234 234: def get_lock (key) 235: 236: lock = @locks[key] 237: 238: return nil unless lock 239: 240: l, lt = lock 241: 242: if (Time.now.to_i - lt) > @lock_max_age 243: @locks.delete key 244: return nil 245: end 246: 247: [ l, lt ] 248: end
Will raise an exception if the locker is not holding a lock for the given key.
# File lib/openwfe/worklist/storelocks.rb, line 271 271: def holding_lock? (locker, key) 272: 273: lock = get_lock key 274: raise "not locked" unless lock 275: l, lt = lock 276: raise "locked by someone else" if (l != locker) 277: # else, simply end 278: end
Returns true if the object is locked
# File lib/openwfe/worklist/storelocks.rb, line 253 253: def locked? (key) 254: 255: @locks[key] != nil 256: end
Will raise an exception if the object (designated via its key) is already locked.
# File lib/openwfe/worklist/storelocks.rb, line 262 262: def not_locked? (key) 263: 264: raise "already locked" if get_lock key 265: end