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) }