Class: SdbLock
- Inherits:
-
Object
- Object
- SdbLock
- Defined in:
- lib/sdb_lock.rb,
lib/sdb_lock/version.rb
Overview
Lock using SimpleDB conditional put.
Create instance. lock = SdbLock.new(‘my_app_lock’, access_key_id: YOUR_AWS_ACCESS_KEY, secret_access_key: YOUR_AWS_SECRET)
Or if you set up AWS account in another way. lock = SdbLock.new(‘my_app_lock’)
Try lock, unlock. lock_gained = lock.try_lock(“abc”) lock.unlock(“abc”) if lock_gained
Try lock with block. It unlocks after block execution is finished. executed = lock.try_lock(“abc”) do
# some work
end
Unlock old ones. lock.unlock_old(60) # Unlock all of older than 60 secs
Constant Summary collapse
- LOCK_TIME =
Attribute name to be used to save locked time
'lock_time'
- MAX_WAIT_SECS =
Max wait secs for #lock
2
- VERSION =
"0.1.1"
Instance Method Summary collapse
-
#initialize(domain_name, options = {}) ⇒ SdbLock
constructor
Constructor.
-
#lock(resource_name, additional_attributes = []) ⇒ Object
lock resource_name It blocks until lock is succeeded.
-
#locked_resources(age_in_seconds = nil) ⇒ Object
All locked resources.
-
#locked_time(resource_name) ⇒ Time
Locked time for resource_name.
-
#try_lock(resource_name, additional_attributes = []) ⇒ TrueClass
Try to lock resource_name.
-
#unlock(resource_name, expected_lock_time = nil) ⇒ Object
Unlock resource_name.
-
#unlock_old(age_in_seconds) ⇒ Array<String>
Unlock old resources.
Constructor Details
#initialize(domain_name, options = {}) ⇒ SdbLock
Constructor
36 37 38 39 40 41 42 43 |
# File 'lib/sdb_lock.rb', line 36 def initialize(domain_name, = {}) @sdb = ::Aws::SimpleDB::Client.new() @domain_name = domain_name unless domains.include? @domain_name @sdb.create_domain(domain_name: @domain_name) @domains = @sdb.list_domains.domain_names end end |
Instance Method Details
#lock(resource_name, additional_attributes = []) ⇒ Object
lock resource_name It blocks until lock is succeeded.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/sdb_lock.rb', line 84 def lock(resource_name, additional_attributes = []) wait_secs = 0.5 while true lock = try_lock(resource_name, additional_attributes) break if lock sleep([wait_secs, MAX_WAIT_SECS].min) wait_secs *= 2 end if block_given? begin yield ensure unlock(resource_name) end else true end end |
#locked_resources(age_in_seconds = nil) ⇒ Object
All locked resources
141 142 143 144 145 146 147 148 149 |
# File 'lib/sdb_lock.rb', line 141 def locked_resources(age_in_seconds = nil) if age_in_seconds cond = older_than(age_in_seconds) else cond = "`#{LOCK_TIME}` is not null" end statement = "SELECT * FROM #{@domain_name} WHERE #{cond}" @sdb.select(select_expression: statement).items.map { |i| i.name } end |
#locked_time(resource_name) ⇒ Time
Locked time for resource_name
129 130 131 132 133 134 135 136 |
# File 'lib/sdb_lock.rb', line 129 def locked_time(resource_name) attributes = item(resource_name) unless attributes.empty? attributes.each do |a| break Time.at(a.value.to_i) if a.name == LOCK_TIME end end end |
#try_lock(resource_name, additional_attributes = []) ⇒ TrueClass
Try to lock resource_name
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/sdb_lock.rb', line 50 def try_lock(resource_name, additional_attributes = []) attributes = [ { name: LOCK_TIME, value: format_time(Time.now) } ].concat(additional_attributes) @sdb.put_attributes( domain_name: @domain_name, item_name: resource_name, attributes: attributes, expected: { name: LOCK_TIME, exists: false } ) if block_given? begin yield ensure unlock(resource_name) end end true rescue ::Aws::SimpleDB::Errors::ConditionalCheckFailed false end |
#unlock(resource_name, expected_lock_time = nil) ⇒ Object
Unlock resource_name
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/sdb_lock.rb', line 106 def unlock(resource_name, expected_lock_time = nil) expected = if expected_lock_time { name: LOCK_TIME, value: expected_lock_time, exists: true } else {} end @sdb.delete_attributes( domain_name: @domain_name, item_name: resource_name, expected: expected ) true rescue ::Aws::SimpleDB::Errors::ConditionalCheckFailed false end |
#unlock_old(age_in_seconds) ⇒ Array<String>
Unlock old resources. It is needed if any program failed to unlock by an unexpected exception or network failure etc.
157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/sdb_lock.rb', line 157 def unlock_old(age_in_seconds) targets = locked_resources(age_in_seconds) unlocked = [] targets.each do |resource_name| value = item(resource_name).each do |attribute| break attribute.value if attribute.name == LOCK_TIME end next if !value || value > format_time(Time.now - age_in_seconds) succ = unlock(resource_name, value) unlocked << resource_name if succ end unlocked end |