X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/9d3ace1fdba783134eb5557a9b28f8132df552de..cb690390d4f253c3bbb9c543e243cf988f39fbb3:/services/api/app/controllers/arvados/v1/containers_controller.rb diff --git a/services/api/app/controllers/arvados/v1/containers_controller.rb b/services/api/app/controllers/arvados/v1/containers_controller.rb index acb61c6e60..13aa478d26 100644 --- a/services/api/app/controllers/arvados/v1/containers_controller.rb +++ b/services/api/app/controllers/arvados/v1/containers_controller.rb @@ -2,6 +2,8 @@ # # SPDX-License-Identifier: AGPL-3.0 +require 'update_priorities' + class Arvados::V1::ContainersController < ApplicationController accept_attribute_as_json :environment, Hash accept_attribute_as_json :mounts, Hash @@ -29,17 +31,16 @@ class Arvados::V1::ContainersController < ApplicationController end def update - if (resource_attrs.keys - [:cost, :gateway_address, :output_properties, :progress, :runtime_status]).empty? + if (resource_attrs.keys.map(&:to_sym) - [:cost, :gateway_address, :output_properties, :progress, :runtime_status]).empty? # If no attributes are being updated besides these, there are no - # cascading changes to other rows/tables, so we should just use - # row locking. - @object.reload(lock: true) + # cascading changes to other rows/tables, the only lock will the + # single row lock on SQL UPDATE. super else - # Lock containers table to avoid deadlock in cascading priority - # update (see #20240) Container.transaction do - ActiveRecord::Base.connection.execute "LOCK TABLE containers IN EXCLUSIVE MODE" + # Get locks ahead of time to avoid deadlock in cascading priority + # update + row_lock_for_priority_update @object.uuid super end end @@ -58,9 +59,8 @@ class Arvados::V1::ContainersController < ApplicationController # @select here to stick, we have to set @preserve_select. @select = @preserve_select = %w(uuid state priority auth_uuid locked_by_uuid) elsif action_name == 'update_priority' - # We're going to reload(lock: true) in the handler, which will - # select all attributes, but will fail if we don't select :id - # now. + # We're going to reload in update_priority!, which will select + # all attributes, but will fail if we don't select :id now. @objects = @objects.select(:id, :uuid) end end @@ -76,13 +76,8 @@ class Arvados::V1::ContainersController < ApplicationController end def update_priority - # Lock containers table to avoid deadlock in cascading priority update (see #20240) - Container.transaction do - ActiveRecord::Base.connection.execute "LOCK TABLE containers IN EXCLUSIVE MODE" - @object.reload(lock: true) - @object.update_priority! - show - end + @object.update_priority! + show end def current