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