lib/sdb_lock.rb in sdb_lock-0.0.2 vs lib/sdb_lock.rb in sdb_lock-0.1.0
- old
+ new
@@ -1,9 +1,8 @@
require "sdb_lock/version"
+require 'aws-sdk'
-require 'aws'
-
# 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)
#
@@ -33,35 +32,48 @@
# Constructor
#
# @param [String] domain_name SimpleDB domain name
# @param [Hash] options
def initialize(domain_name, options = {})
- @sdb = AWS::SimpleDB.new(options)
- options = options.dup
- if options.has_key?(:create_domain)
- @sdb.domains.create(domain_name) if options[:create_domain]
- options.delete(:create_domain)
+ @sdb = ::Aws::SimpleDB::Client.new(options)
+ @domain_name = domain_name
+ unless domains.include? @domain_name
+ @sdb.create_domain(domain_name: @domain_name)
+ @domains = @sdb.list_domains.domain_names
end
- @domain = @sdb.domains[domain_name]
end
# Try to lock resource_name
#
# @param [String] resource_name name to lock
# @return [TrueClass] true when locked, unless false
def try_lock(resource_name)
- attributes = {LOCK_TIME => format_time(Time.now), unless: LOCK_TIME}
- item(resource_name).attributes.set(attributes)
+ attributes = [
+ {
+ name: LOCK_TIME,
+ value: format_time(Time.now)
+ }
+ ]
+
+ @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
+ rescue ::Aws::SimpleDB::Errors::ConditionalCheckFailed
false
end
# lock resource_name
# It blocks until lock is succeeded.
@@ -88,26 +100,39 @@
end
# Unlock resource_name
# @param [String] resource_name name to unlock
def unlock(resource_name, expected_lock_time = nil)
- if expected_lock_time
- item(resource_name).attributes.delete(LOCK_TIME, if: {LOCK_TIME => expected_lock_time})
+ expected = if expected_lock_time
+ {
+ name: LOCK_TIME,
+ value: expected_lock_time,
+ exists: true
+ }
else
- item(resource_name).attributes.delete(LOCK_TIME)
+ {}
end
+
+ @sdb.delete_attributes(
+ domain_name: @domain_name,
+ item_name: resource_name,
+ expected: expected
+ )
true
- rescue AWS::SimpleDB::Errors::ConditionalCheckFailed
+ rescue ::Aws::SimpleDB::Errors::ConditionalCheckFailed
false
end
# Locked time for resource_name
# @return [Time] locked time, nil if it is not locked
def locked_time(resource_name)
- attribute = item(resource_name).attributes[LOCK_TIME]
- lock_time_string = attribute.values.first
- Time.at(lock_time_string.to_i) if lock_time_string
+ 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
# All locked resources
#
# @param [Fixnum] age_in_seconds select resources older than this seconds
@@ -115,11 +140,12 @@
if age_in_seconds
cond = older_than(age_in_seconds)
else
cond = "`#{LOCK_TIME}` is not null"
end
- @domain.items.where(cond).map(&:name)
+ statement = "SELECT * FROM #{@domain_name} WHERE #{cond}"
+ @sdb.select(select_expression: statement).items.map { |i| i.name }
end
# Unlock old resources.
# It is needed if any program failed to unlock by an unexpected exception
# or network failure etc.
@@ -128,21 +154,30 @@
# @return [Array<String>] unlocked resource names
def unlock_old(age_in_seconds)
targets = locked_resources(age_in_seconds)
unlocked = []
targets.each do |resource_name|
- values = item(resource_name).attributes[LOCK_TIME].values
- next if !values || !values.first || values.first > format_time(Time.now - age_in_seconds)
- succ = unlock(resource_name, values.first)
+ 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
private
+ def domains
+ @domains ||= @sdb.list_domains.domain_names
+ end
+
def item(resource_name)
- @domain.items[resource_name]
+ @sdb.get_attributes(
+ domain_name: @domain_name,
+ item_name: resource_name
+ ).attributes
end
# Format time to compare lexicographically
def format_time(time)
# 12 digits is enough until year 9999