class Locker::Label::Label
Proper Resource
class
Attributes
id[R]
Public Class Methods
create(key)
click to toggle source
# File lib/locker/label.rb, line 33 def self.create(key) raise 'Label key already exists' if Label.exists?(key) redis.sadd('label-list', Label.normalize(key)) l = Label.new(key) l.state = 'unlocked' l.owner_id = '' l.log('Created') l end
delete(key)
click to toggle source
# File lib/locker/label.rb, line 43 def self.delete(key) raise 'Unknown label key' unless Label.exists?(key) %w[state owner_id membership wait_queue journal observer_ids].each do |item| redis.del("label:#{key}:#{item}") end redis.srem('label-list', Label.normalize(key)) end
exists?(key)
click to toggle source
# File lib/locker/label.rb, line 29 def self.exists?(key) redis.sismember('label-list', Label.normalize(key)) end
list()
click to toggle source
# File lib/locker/label.rb, line 51 def self.list redis.smembers('label-list').sort end
new(key)
click to toggle source
# File lib/locker/label.rb, line 24 def initialize(key) raise 'Unknown label key' unless Label.exists?(key) @id = Label.normalize(key) end
normalize(key)
click to toggle source
# File lib/locker/label.rb, line 55 def self.normalize(key) key.strip.downcase end
Public Instance Methods
add_observer!(observer_id)
click to toggle source
# File lib/locker/label.rb, line 127 def add_observer!(observer_id) observer_ids.add(observer_id) end
add_resource(resource)
click to toggle source
# File lib/locker/label.rb, line 149 def add_resource(resource) log("Resource #{resource.id} added") resource.labels << id membership << resource.id end
dedupe!()
click to toggle source
# File lib/locker/label.rb, line 119 def dedupe! queued = wait_queue.to_a wait_queue.clear queued.chunk { |x| x }.map(&:first).each do |user| wait_queue << user end end
give!(recipient_id)
click to toggle source
# File lib/locker/label.rb, line 112 def give!(recipient_id) log("Given from #{owner.id} to #{recipient_id}") wait_queue.unshift(recipient_id) dedupe! unlock! end
held_for()
click to toggle source
# File lib/locker/label.rb, line 166 def held_for return '' unless locked? TimeLord::Time.new(Time.parse(taken_at.value) - 1).period.to_words end
lock!(owner_id)
click to toggle source
# File lib/locker/label.rb, line 59 def lock!(owner_id) if locked? wait_queue << owner_id if wait_queue.last != owner_id return false end coord_lock.lock do membership.each do |resource_name| r = Locker::Resource::Resource.new(resource_name) return false if r.locked? end # TODO: read-modify-write cycle, not the best membership.each do |resource_name| r = Locker::Resource::Resource.new(resource_name) r.lock!(owner_id) end self.owner_id = owner_id self.state = 'locked' self.taken_at = Time.now.utc end u = Lita::User.fuzzy_find(owner_id) log("Locked by #{u.name}") true end
locked?()
click to toggle source
# File lib/locker/label.rb, line 139 def locked? (state == 'locked') end
log(statement)
click to toggle source
# File lib/locker/label.rb, line 185 def log(statement) journal << "#{Time.now.utc}: #{statement}" end
observer?(observer_id)
click to toggle source
# File lib/locker/label.rb, line 135 def observer?(observer_id) observer_ids.member?(observer_id) end
observers()
click to toggle source
# File lib/locker/label.rb, line 143 def observers observer_ids.map do |observer_id| Lita::User.find_by_id(observer_id) end end
owner()
click to toggle source
# File lib/locker/label.rb, line 161 def owner return nil unless locked? Lita::User.find_by_id(owner_id.value) end
remove_observer!(observer_id)
click to toggle source
# File lib/locker/label.rb, line 131 def remove_observer!(observer_id) observer_ids.delete(observer_id) end
remove_resource(resource)
click to toggle source
# File lib/locker/label.rb, line 155 def remove_resource(resource) log("Resource #{resource.id} removed") resource.labels.delete(id) membership.delete(resource.id) end
steal!(owner_id)
click to toggle source
# File lib/locker/label.rb, line 105 def steal!(owner_id) log("Stolen from #{owner.id} to #{owner_id}") wait_queue.unshift(owner_id) dedupe! unlock! end
to_json()
click to toggle source
# File lib/locker/label.rb, line 171 def to_json val = { id: id, state: state.value, membership: membership } if locked? val[:owner_id] = owner_id.value val[:taken_at] = taken_at.value val[:wait_queue] = wait_queue end val.to_json end
unlock!()
click to toggle source
# File lib/locker/label.rb, line 84 def unlock! return true if state == 'unlocked' coord_lock.lock do self.owner_id = '' self.state = 'unlocked' self.taken_at = '' membership.each do |resource_name| r = Locker::Resource::Resource.new(resource_name) r.unlock! end end log('Unlocked') # FIXME: Possible race condition where resources become unavailable between unlock and relock if wait_queue.count > 0 next_user = wait_queue.shift lock!(next_user) end true end