Class: NoBrainer::Lock
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Autoload
#autoload, #autoload_and_include, #eager_autoload, #eager_load!, extended
Constructor Details
#initialize(key, options = {}) ⇒ Lock
Returns a new instance of Lock.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/no_brainer/lock.rb', line 21
def initialize(key, options={})
if options[:from_db]
super
self.instance_token = get_new_instance_token
else
@default_options = options.slice(:expire, :timeout)
options.delete(:expire); options.delete(:timeout);
key = key.to_s if key.is_a?(Symbol)
super(options.merge(:key => key))
raise ArgumentError unless valid?
end
end
|
Class Method Details
.find(key) ⇒ Object
17
18
19
|
# File 'lib/no_brainer/lock.rb', line 17
def self.find(key)
super(Digest::SHA1.base64digest(key.to_s))
end
|
Instance Method Details
#delete ⇒ Object
116
|
# File 'lib/no_brainer/lock.rb', line 116
def delete(*); raise NotImplementedError; end
|
#get_new_instance_token ⇒ Object
#lock(options = {}) ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# File 'lib/no_brainer/lock.rb', line 49
def lock(options={})
options.assert_valid_keys(:expire, :timeout)
timeout = get_option_value(options, :timeout)
sleep_amount = 0.1
start_at = Time.now
loop do
return if try_lock(options.slice(:expire))
raise_lock_unavailable! if Time.now - start_at + sleep_amount > timeout
sleep(sleep_amount)
sleep_amount = [1, sleep_amount * 2].min
end
end
|
#refresh(options = {}) ⇒ Object
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
# File 'lib/no_brainer/lock.rb', line 93
def refresh(options={})
options.assert_valid_keys(:expire)
raise_unless_locked!
set_expiration(options.merge(:use_previous_expire => true))
result = NoBrainer.run do |r|
selector.update do |doc|
r.branch(doc[:instance_token].eq(self.instance_token),
{ :expires_at => self.expires_at }, nil)
end
end
unless result['replaced'] == 1
@locked = false
raise_lost_lock!
end
end
|
115
|
# File 'lib/no_brainer/lock.rb', line 115
def save?(*); raise NotImplementedError; end
|
#synchronize(options = {}, &block) ⇒ Object
40
41
42
43
44
45
46
47
|
# File 'lib/no_brainer/lock.rb', line 40
def synchronize(options={}, &block)
lock(options)
begin
block.call
ensure
unlock if @locked
end
end
|
#try_lock(options = {}) ⇒ Object
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# File 'lib/no_brainer/lock.rb', line 63
def try_lock(options={})
options.assert_valid_keys(:expire)
raise_if_locked!
set_expiration(options)
result = NoBrainer.run do |r|
selector.replace do |doc|
r.branch(doc.eq(nil).or(doc[:expires_at] < r.now),
self.attributes, doc)
end
end
return @locked = (result['inserted'] + result['replaced']) == 1
end
|
#unlock ⇒ Object
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/no_brainer/lock.rb', line 79
def unlock
raise_unless_locked!
result = NoBrainer.run do |r|
selector.replace do |doc|
r.branch(doc[:instance_token].default(nil).eq(self.instance_token),
nil, doc)
end
end
@locked = false
raise_lost_lock! unless result['deleted'] == 1
end
|