Class OpenWFE::StoreWithLocks
In: lib/openwfe/worklist/storelocks.rb
Parent: Object

A wrapper for a Store[Participant] that includes a lock system.

Methods

Included Modules

Contextual

Constants

DEFAULT_LOCK_MAX_AGE = "1h"

Attributes

lock_max_age  [RW] 
store  [R] 

Public Class methods

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).

[Source]

    # 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

Public Instance methods

Sets the application context of this store lock and of the real store behind.

[Source]

     # 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

Just calls the consume method of the underlying store.

[Source]

     # File lib/openwfe/worklist/storelocks.rb, line 203
203:         def consume (workitem)
204: 
205:             @store.consume workitem
206:         end

Iterates over the workitems in the store.

Doesn‘t care about any order for now.

[Source]

     # 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

Forwards the workitem (to the engine) and releases the lock on it (of course, it‘s not in the store anymore).

[Source]

     # File lib/openwfe/worklist/storelocks.rb, line 177
177:         def forward (locker, workitem)
178: 
179:             save_or_forward :forward, locker, workitem
180:         end

Gets a workitem without locking it.

[Source]

     # 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.

[Source]

     # 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).

[Source]

     # 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.

[Source]

     # 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
lock(locker, key)

Alias for get_and_lock

proceed(locker, workitem)

Alias for forward

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.

[Source]

     # 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

Saves the workitem and releases the lock on it.

[Source]

     # File lib/openwfe/worklist/storelocks.rb, line 168
168:         def save (locker, workitem)
169: 
170:             save_or_forward :save, locker, workitem
171:         end

Returns the count of workitems in the store.

[Source]

     # File lib/openwfe/worklist/storelocks.rb, line 195
195:         def size
196: 
197:             @store.size
198:         end

Protected Instance methods

Returns the lock info (else nil) for the given key.

[Source]

     # 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.

[Source]

     # 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

[Source]

     # 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.

[Source]

     # File lib/openwfe/worklist/storelocks.rb, line 262
262:             def not_locked? (key)
263: 
264:                 raise "already locked" if get_lock key
265:             end

[Source]

     # File lib/openwfe/worklist/storelocks.rb, line 222
222:             def save_or_forward (method, locker, workitem)
223: 
224:                 @lock_mutex.synchronize do
225:                     holding_lock? locker, workitem.fei
226:                     @locks.delete workitem.fei
227:                     @store.send method, workitem
228:                 end
229:             end

[Validate]