app/models/foreman_tasks/lock.rb in foreman-tasks-0.5.2 vs app/models/foreman_tasks/lock.rb in foreman-tasks-0.5.3

- old
+ new

@@ -1,14 +1,14 @@ module ForemanTasks class Lock < ActiveRecord::Base - LINK_LOCK_NAME = :link_resource + LINK_LOCK_NAME = :link_resource OWNER_LOCK_NAME = :task_owner # not really intedet to be created in database, but it's used for # explicitly stating that the all the locks for resource should be used - ALL_LOCK_NAME = :all + ALL_LOCK_NAME = :all RESERVED_LOCK_NAMES = [LINK_LOCK_NAME, OWNER_LOCK_NAME, ALL_LOCK_NAME] class LockConflict < StandardError attr_reader :required_lock, :conflicting_locks @@ -29,29 +29,29 @@ validates :task_id, :name, :resource_id, :resource_type, presence: true validate do unless available? - raise LockConflict.new(self, coliding_locks) + raise LockConflict.new(self, colliding_locks) end end # returns true if it's possible to aquire this kind of lock def available? - return true unless coliding_locks.any? + not colliding_locks.any? end - # returns a scope of the locks coliding with this one - def coliding_locks - coliding_locks_scope = Lock.active.where('foreman_tasks_locks.task_id != ?', task_id) - coliding_locks_scope = coliding_locks_scope.where(name: name, - resource_id: resource_id, - resource_type: resource_type) + # returns a scope of the locks colliding with this one + def colliding_locks + colliding_locks_scope = Lock.active.where(Lock.arel_table[:task_id].not_eq(task_id)) + colliding_locks_scope = colliding_locks_scope.where(name: name, + resource_id: resource_id, + resource_type: resource_type) unless self.exclusive? - coliding_locks_scope = coliding_locks_scope.where(:exclusive => true) + colliding_locks_scope = colliding_locks_scope.where(:exclusive => true) end - return coliding_locks_scope + return colliding_locks_scope end class << self # Locks the resource so that no other task can lock it while running. @@ -61,11 +61,11 @@ def exclusive!(resource, uuid) build_exclusive_locks(resource, uuid).each(&:save!) end def exclusive?(resource) - build_exclusive_locks(resource).all?(:available?) + build_exclusive_locks(resource).all?(&:available?) end # Locks the resource so that no other task can lock it while running. # Other not-locking tasks are tolerated. @@ -80,14 +80,23 @@ # the related resources (recursively) and links the task to them as well. def lock!(resource, uuid, *lock_names) build_locks(resource, lock_names, uuid).each(&:save!) end - def lock?(resource, uuid, *lock_names) + def lockable?(resource, uuid, *lock_names) build_locks(resource, lock_names, uuid).all?(&:available?) end + def locked?(resource, uuid, *lock_names) + not lockable?(resource, uuid, *lock_names) + end + + def colliding_locks(resource, uuid, *lock_names) + build_locks(resource, lock_names, uuid). + inject([]) { |collisions, lock| collisions.concat lock.colliding_locks.to_a } + end + # Assigns the resource to the task to easily track the task in context of # the resource. This doesn't prevent other actions to lock the resource # and should be used only for actions that tolerate other actions to be # performed on the resource. Usually, this shouldn't needed to be done # through the action directly, because the lock should assign it's parrent @@ -109,10 +118,10 @@ private def all_lock_names(resource, include_links = false) lock_names = [] if resource.class.respond_to?(:available_locks) && - resource.class.available_locks.any? + resource.class.available_locks.any? lock_names.concat(resource.class.available_locks) else raise "The resource #{resource.class.name} doesn't define any available lock" end if lock_names.any? { |lock_name| RESERVED_LOCK_NAMES.include?(lock_name) }