Class: ForemanTasks::Lock
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ForemanTasks::Lock
- Defined in:
- app/models/foreman_tasks/lock.rb
Defined Under Namespace
Classes: LockConflict
Constant Summary collapse
- LINK_LOCK_NAME =
:link_resource
- OWNER_LOCK_NAME =
:task_owner
- ALL_LOCK_NAME =
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
- RESERVED_LOCK_NAMES =
[LINK_LOCK_NAME, OWNER_LOCK_NAME, ALL_LOCK_NAME]
Class Method Summary collapse
- .colliding_locks(resource, uuid, *lock_names) ⇒ Object
-
.exclusive!(resource, uuid) ⇒ Object
Locks the resource so that no other task can lock it while running.
- .exclusive?(resource) ⇒ Boolean
-
.link!(resource, uuid) ⇒ Object
Assigns the resource to the task to easily track the task in context of the resource.
- .link?(resource, uuid) ⇒ Boolean
-
.lock!(resource, uuid, *lock_names) ⇒ Object
Locks the resource so that no other task can lock it while running.
- .lockable?(resource, uuid, *lock_names) ⇒ Boolean
- .locked?(resource, uuid, *lock_names) ⇒ Boolean
-
.owner!(user, uuid) ⇒ Object
Records the information about the user that triggered the task.
Instance Method Summary collapse
-
#available? ⇒ Boolean
returns true if it’s possible to aquire this kind of lock.
-
#colliding_locks ⇒ Object
returns a scope of the locks colliding with this one.
Class Method Details
.colliding_locks(resource, uuid, *lock_names) ⇒ Object
109 110 111 112 |
# File 'app/models/foreman_tasks/lock.rb', line 109 def colliding_locks(resource, uuid, *lock_names) build_locks(resource, lock_names, uuid). inject([]) { |collisions, lock| collisions.concat lock.colliding_locks.to_a } end |
.exclusive!(resource, uuid) ⇒ Object
Locks the resource so that no other task can lock it while running. No other task related to the resource is not allowed (even not-locking ones) A typical usecase is resource deletion, where it’s good idea to make sure nothing else related to the resource is really running.
77 78 79 |
# File 'app/models/foreman_tasks/lock.rb', line 77 def exclusive!(resource, uuid) build_exclusive_locks(resource, uuid).each(&:save!) end |
.exclusive?(resource) ⇒ Boolean
81 82 83 |
# File 'app/models/foreman_tasks/lock.rb', line 81 def exclusive?(resource) build_exclusive_locks(resource).all?(&:available?) end |
.link!(resource, uuid) ⇒ Object
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 objects to the action srecursively (using related_resources
method in model objects)
121 122 123 |
# File 'app/models/foreman_tasks/lock.rb', line 121 def link!(resource, uuid) build_link(resource, uuid).save! end |
.link?(resource, uuid) ⇒ Boolean
125 126 127 |
# File 'app/models/foreman_tasks/lock.rb', line 125 def link?(resource, uuid) build_link(resource, uuid).available? end |
.lock!(resource, uuid, *lock_names) ⇒ Object
Locks the resource so that no other task can lock it while running. Other not-locking tasks are tolerated.
The lock names allow to specify what locks should be activated. It has to be a subset of names defined in model’s class available_locks method
When no lock name is specified, the resource is locked against all the available locks.
It also looks at related_resources
method of the resource to calcuate all the related resources (recursively) and links the task to them as well.
97 98 99 |
# File 'app/models/foreman_tasks/lock.rb', line 97 def lock!(resource, uuid, *lock_names) build_locks(resource, lock_names, uuid).each(&:save!) end |
.lockable?(resource, uuid, *lock_names) ⇒ Boolean
101 102 103 |
# File 'app/models/foreman_tasks/lock.rb', line 101 def lockable?(resource, uuid, *lock_names) build_locks(resource, lock_names, uuid).all?(&:available?) end |
.locked?(resource, uuid, *lock_names) ⇒ Boolean
105 106 107 |
# File 'app/models/foreman_tasks/lock.rb', line 105 def locked?(resource, uuid, *lock_names) not lockable?(resource, uuid, *lock_names) end |
.owner!(user, uuid) ⇒ Object
Records the information about the user that triggered the task
130 131 132 |
# File 'app/models/foreman_tasks/lock.rb', line 130 def owner!(user, uuid) build_owner(user, uuid).save! end |
Instance Method Details
#available? ⇒ Boolean
returns true if it’s possible to aquire this kind of lock
54 55 56 |
# File 'app/models/foreman_tasks/lock.rb', line 54 def available? not colliding_locks.any? end |
#colliding_locks ⇒ Object
returns a scope of the locks colliding with this one
59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/models/foreman_tasks/lock.rb', line 59 def colliding_locks task_ids = task.self_and_parents.map(&:id) colliding_locks_scope = Lock.active.where(Lock.arel_table[:task_id].not_in(task_ids)) colliding_locks_scope = colliding_locks_scope.where(name: name, resource_id: resource_id, resource_type: resource_type) unless self.exclusive? colliding_locks_scope = colliding_locks_scope.where(:exclusive => true) end return colliding_locks_scope end |