Class: OpenWFE::StoreWithLocks

Inherits:
Object
  • Object
show all
Includes:
Contextual
Defined in:
lib/openwfe/worklist/storelocks.rb

Overview

A wrapper for a Store that includes a lock system.

Constant Summary collapse

DEFAULT_LOCK_MAX_AGE =
"1h"

Instance Attribute Summary collapse

Attributes included from Contextual

#application_context

Instance Method Summary collapse

Methods included from Contextual

#get_work_directory, #init_service, #lookup

Constructor Details

#initialize(real_store, application_context = nil, params = {}) ⇒ StoreWithLocks

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



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/openwfe/worklist/storelocks.rb', line 82

def initialize (real_store, application_context=nil, params={})

    @store = real_store
    @store = @store.new if @store.kind_of?(Class)

    self.application_context = application_context

    @lock_max_age = params[:lock_max_age] || DEFAULT_LOCK_MAX_AGE
    @lock_max_age = Rufus::parse_time_string @lock_max_age

    @locks = {}
    @lock_mutex = Mutex.new
end

Instance Attribute Details

#lock_max_ageObject

Returns the value of attribute lock_max_age.



61
62
63
# File 'lib/openwfe/worklist/storelocks.rb', line 61

def lock_max_age
  @lock_max_age
end

#storeObject (readonly)

Returns the value of attribute store.



62
63
64
# File 'lib/openwfe/worklist/storelocks.rb', line 62

def store
  @store
end

Instance Method Details

#application_context=(ac) ⇒ Object

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



100
101
102
103
104
105
106
107
108
109
# File 'lib/openwfe/worklist/storelocks.rb', line 100

def application_context= (ac)

    @application_context = ac

    if @store.respond_to?(:application_context=) and \
        not store.application_context

        @store.application_context = @application_context
    end
end

#consume(workitem) ⇒ Object

Just calls the consume method of the underlying store.



203
204
205
206
# File 'lib/openwfe/worklist/storelocks.rb', line 203

def consume (workitem)

    @store.consume workitem
end

#each(&block) ⇒ Object

Iterates over the workitems in the store.

Doesn’t care about any order for now.



213
214
215
216
217
218
# File 'lib/openwfe/worklist/storelocks.rb', line 213

def each (&block) # :yields: workitem, locked

    @store.each do |fei, workitem|
        block.call workitem, locked?(fei)
    end
end

#forward(locker, workitem) ⇒ Object Also known as: proceed

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



177
178
179
180
# File 'lib/openwfe/worklist/storelocks.rb', line 177

def forward (locker, workitem)

    save_or_forward :forward, locker, workitem
end

#get(key) ⇒ Object

Gets a workitem without locking it.



135
136
137
138
# File 'lib/openwfe/worklist/storelocks.rb', line 135

def get (key)

    @store[key]
end

#get_and_lock(locker, key) ⇒ Object Also known as: lock

Get a workitem, lock it and then return it. Ensures that no other ‘locker’ can lock it meanwhile.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/openwfe/worklist/storelocks.rb', line 115

def get_and_lock (locker, key)

    @lock_mutex.synchronize do

        object = @store[key]

        return nil unless object

        not_locked?(key)

        @locks[key] = [ locker, Time.now.to_i ]
        object
    end
end

#get_locker(key) ⇒ Object

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



158
159
160
161
162
163
# File 'lib/openwfe/worklist/storelocks.rb', line 158

def get_locker (key)

    lock = get_lock key
    return nil unless lock
    lock[0]
end

#list_workitems(workflow_instance_id = nil) ⇒ Object

Directly forwards the list_workitems() call to the wrapped store.



187
188
189
190
# File 'lib/openwfe/worklist/storelocks.rb', line 187

def list_workitems (workflow_instance_id=nil)

    @store.list_workitems(workflow_instance_id)
end

#release(locker, key) ⇒ Object

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.



145
146
147
148
149
150
151
# File 'lib/openwfe/worklist/storelocks.rb', line 145

def release (locker, key)

    @lock_mutex.synchronize do
        holding_lock? locker, key
        @locks.delete key
    end
end

#save(locker, workitem) ⇒ Object

Saves the workitem and releases the lock on it.



168
169
170
171
# File 'lib/openwfe/worklist/storelocks.rb', line 168

def save (locker, workitem)

    save_or_forward :save, locker, workitem
end

#sizeObject

Returns the count of workitems in the store.



195
196
197
198
# File 'lib/openwfe/worklist/storelocks.rb', line 195

def size

    @store.size
end