| 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