Merge branch '21026-sanitize-html-doc'
[arvados.git] / services / api / lib / update_priorities.rb
index 66d307436e29df7bdc408334287f41bc16c36dbe..94115340df3c7fb807acfba0c90ff49d95020107 100644 (file)
@@ -2,9 +2,30 @@
 #
 # SPDX-License-Identifier: AGPL-3.0
 
+def row_lock_for_priority_update container_uuid
+  # Locks all the containers under this container, and also any
+  # immediate parent containers.  This ensures we have locked
+  # everything that gets touched by either a priority update or state
+  # update.
+  ActiveRecord::Base.connection.exec_query %{
+        select 1 from containers where containers.uuid in (
+  select pri_container_uuid from container_tree($1)
+UNION
+  select container_requests.requesting_container_uuid from container_requests
+    where container_requests.container_uuid = $1
+          and container_requests.state = 'Committed'
+          and container_requests.requesting_container_uuid is not NULL
+)
+        order by containers.uuid for update
+  }, 'select_for_update_priorities', [container_uuid]
+end
+
 def update_priorities starting_container_uuid
+  # Ensure the row locks were taken in order
+  row_lock_for_priority_update starting_container_uuid
+
   ActiveRecord::Base.connection.exec_query %{
-update containers set priority=computed.priority from (select pri_container_uuid, priority from update_priorities($1) order by pri_container_uuid) as computed
- where containers.uuid = computed.pri_container_uuid
-}, 'update_priorities', [[nil, starting_container_uuid]]
+update containers set priority=computed.upd_priority from container_tree_priorities($1) as computed
+ where containers.uuid = computed.pri_container_uuid and priority != computed.upd_priority
+}, 'update_priorities', [starting_container_uuid]
 end