lib/locker/resource.rb in lita-locker-0.7.0 vs lib/locker/resource.rb in lita-locker-1.0.0
- old
+ new
@@ -1,48 +1,83 @@
# Locker subsystem
module Locker
# Resource helpers
module Resource
- def resource(name)
- redis.hgetall("resource_#{name}")
- end
+ # Proper Resource class
+ class Resource
+ include Redis::Objects
- def resources
- redis.keys('resource_*')
- end
+ value :state
+ value :owner_id
+ set :labels
- def resource_exists?(name)
- redis.exists("resource_#{name}")
- end
+ lock :coord, expiration: 5
- def lock_resource!(name, owner, time_until)
- return false unless resource_exists?(name)
- resource_key = "resource_#{name}"
- value = redis.hget(resource_key, 'state')
- return false unless value == 'unlocked'
- # FIXME: Race condition!
- redis.hset(resource_key, 'state', 'locked')
- redis.hset(resource_key, 'owner_id', owner.id)
- redis.hset(resource_key, 'until', time_until)
- true
- end
+ attr_reader :id
- def unlock_resource!(name)
- return false unless resource_exists?(name)
- key = "resource_#{name}"
- redis.hset(key, 'state', 'unlocked')
- redis.hset(key, 'owner_id', '')
- true
- end
+ def initialize(key)
+ fail 'Unknown resource key' unless Resource.exists?(key)
+ @id = key
+ end
- def create_resource(name)
- resource_key = "resource_#{name}"
- redis.hset(resource_key, 'state', 'unlocked') unless
- resource_exists?(name) || label_exists?(name)
- end
+ def self.exists?(key)
+ redis.sismember('resource-list', key)
+ end
- def delete_resource(name)
- resource_key = "resource_#{name}"
- redis.del(resource_key) if resource_exists?(name)
+ def self.create(key)
+ fail 'Resource key already exists' if Resource.exists?(key)
+ redis.sadd('resource-list', key)
+ r = Resource.new(key)
+ r.state = 'unlocked'
+ r.owner_id = ''
+ r
+ end
+
+ def self.delete(key)
+ fail 'Unknown resource key' unless Resource.exists?(key)
+ %w(state, owner_id).each do |item|
+ redis.del("resource:#{key}:#{item}")
+ end
+ redis.srem('resource-list', key)
+ end
+
+ def self.list
+ redis.smembers('resource-list').sort
+ end
+
+ def lock!(owner_id)
+ return false if state == 'locked'
+ coord_lock.lock do
+ self.owner_id = owner_id
+ self.state = 'locked'
+ end
+ true
+ end
+
+ def unlock!
+ return true if state == 'unlocked'
+ coord_lock.lock do
+ self.owner_id = ''
+ self.state = 'unlocked'
+ end
+ true
+ end
+
+ def locked?
+ (state == 'locked')
+ end
+
+ def owner
+ return nil unless locked?
+ Lita::User.find_by_id(owner_id.value)
+ end
+
+ def to_json
+ {
+ id: id,
+ state: state.value,
+ owner_id: owner_id.value
+ }.to_json
+ end
end
end
end