X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/1471ad4b235e168ccee4fa351b0025b2b380d7ac..39c28fac9320fbee1cc8fc4e92c5e7cca03cccd6:/services/api/app/models/container.rb diff --git a/services/api/app/models/container.rb b/services/api/app/models/container.rb index 1dbdb57105..7176bda926 100644 --- a/services/api/app/models/container.rb +++ b/services/api/app/models/container.rb @@ -5,6 +5,7 @@ require 'log_reuse_info' require 'whitelist_update' require 'safe_json' +require 'update_priority' class Container < ArvadosModel include ArvadosModelUpdates @@ -37,6 +38,7 @@ class Container < ArvadosModel before_save :scrub_secret_mounts after_save :handle_completed after_save :propagate_priority + after_commit { UpdatePriority.run_update_thread } has_many :container_requests, :foreign_key => :container_uuid, :class_name => 'ContainerRequest', :primary_key => :uuid belongs_to :auth, :class_name => 'ApiClientAuthorization', :foreign_key => :auth_uuid, :primary_key => :uuid @@ -126,7 +128,6 @@ class Container < ArvadosModel # Update the priority of child container requests to match new # priority of the parent container (ignoring requests with no # container assigned, because their priority doesn't matter). - ActiveRecord::Base.connection.execute('LOCK container_requests, containers IN EXCLUSIVE MODE') ContainerRequest. where(requesting_container_uuid: self.uuid, state: ContainerRequest::Committed). @@ -227,13 +228,13 @@ class Container < ArvadosModel def self.find_reusable(attrs) log_reuse_info { "starting with #{Container.all.count} container records in database" } - candidates = Container.where_serialized(:command, attrs[:command]) + candidates = Container.where_serialized(:command, attrs[:command], md5: true) log_reuse_info(candidates) { "after filtering on command #{attrs[:command].inspect}" } candidates = candidates.where('cwd = ?', attrs[:cwd]) log_reuse_info(candidates) { "after filtering on cwd #{attrs[:cwd].inspect}" } - candidates = candidates.where_serialized(:environment, attrs[:environment]) + candidates = candidates.where_serialized(:environment, attrs[:environment], md5: true) log_reuse_info(candidates) { "after filtering on environment #{attrs[:environment].inspect}" } candidates = candidates.where('output_path = ?', attrs[:output_path]) @@ -243,13 +244,14 @@ class Container < ArvadosModel candidates = candidates.where('container_image = ?', image) log_reuse_info(candidates) { "after filtering on container_image #{image.inspect} (resolved from #{attrs[:container_image].inspect})" } - candidates = candidates.where_serialized(:mounts, resolve_mounts(attrs[:mounts])) + candidates = candidates.where_serialized(:mounts, resolve_mounts(attrs[:mounts]), md5: true) log_reuse_info(candidates) { "after filtering on mounts #{attrs[:mounts].inspect}" } - candidates = candidates.where('secret_mounts_md5 = ?', Digest::MD5.hexdigest(SafeJSON.dump(self.deep_sort_hash(attrs[:secret_mounts])))) - log_reuse_info(candidates) { "after filtering on mounts #{attrs[:mounts].inspect}" } + secret_mounts_md5 = Digest::MD5.hexdigest(SafeJSON.dump(self.deep_sort_hash(attrs[:secret_mounts]))) + candidates = candidates.where('secret_mounts_md5 = ?', secret_mounts_md5) + log_reuse_info(candidates) { "after filtering on secret_mounts_md5 #{secret_mounts_md5.inspect}" } - candidates = candidates.where_serialized(:runtime_constraints, resolve_runtime_constraints(attrs[:runtime_constraints])) + candidates = candidates.where_serialized(:runtime_constraints, resolve_runtime_constraints(attrs[:runtime_constraints]), md5: true) log_reuse_info(candidates) { "after filtering on runtime_constraints #{attrs[:runtime_constraints].inspect}" } log_reuse_info { "checking for state=Complete with readable output and log..." } @@ -316,10 +318,6 @@ class Container < ArvadosModel # (because state might have changed while acquiring the lock). check_lock_fail transaction do - # Locking involves assigning auth_uuid, which involves looking - # up container requests, so we must lock both tables in the - # proper order to avoid deadlock. - ActiveRecord::Base.connection.execute('LOCK container_requests, containers IN EXCLUSIVE MODE') reload check_lock_fail update_attributes!(state: Locked) @@ -542,7 +540,6 @@ class Container < ArvadosModel if self.state_changed? and self.final? act_as_system_user do - ActiveRecord::Base.connection.execute('LOCK container_requests, containers IN EXCLUSIVE MODE') if self.state == Cancelled retryable_requests = ContainerRequest.where("container_uuid = ? and priority > 0 and state = 'Committed' and container_count < container_count_max", uuid) else