1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
6 extend CurrentApiClient
8 # Clean up after races.
10 # If container priority>0 but there are no committed container
11 # requests for it, reset priority to 0.
13 # If container priority=0 but there are committed container requests
14 # for it with priority>0, update priority.
16 # Normally, update_priority is a no-op if another thread/process is
17 # already updating. Test cases that need to check priorities after
18 # updating can force a (possibly overlapping) update in the current
19 # thread/transaction by setting the "nolock" flag. See #14878.
20 def self.update_priority(nolock: false)
21 if !File.owned?(Rails.root.join('tmp'))
22 Rails.logger.warn("UpdatePriority: not owner of #{Rails.root}/tmp, skipping")
25 lockfile = Rails.root.join('tmp', 'update_priority.lock')
26 File.open(lockfile, File::RDWR|File::CREAT, 0600) do |f|
27 return unless nolock || f.flock(File::LOCK_NB|File::LOCK_EX)
29 # priority>0 but should be 0:
30 ActiveRecord::Base.connection.
31 exec_query("UPDATE containers AS c SET priority=0 WHERE state IN ('Queued', 'Locked', 'Running') AND priority>0 AND uuid NOT IN (SELECT container_uuid FROM container_requests WHERE priority>0 AND state='Committed');", 'UpdatePriority')
33 # priority==0 but should be >0:
36 joins("JOIN container_requests ON container_requests.container_uuid=containers.uuid AND container_requests.state=#{ActiveRecord::Base.connection.quote(ContainerRequest::Committed)} AND container_requests.priority>0").
37 where('containers.state IN (?) AND containers.priority=0 AND container_requests.uuid IS NOT NULL',
38 [Container::Queued, Container::Locked, Container::Running]).
39 map(&:update_priority!)
44 def self.run_update_thread
46 Rails.cache.fetch('UpdatePriority', expires_in: 5.seconds) do
52 Thread.current.abort_on_exception = false
56 Rails.logger.error "#{e.class}: #{e}\n#{e.backtrace.join("\n\t")}"
58 # Rails 5.1+ makes test threads share a database connection, so we can't
59 # close a connection shared with other threads.
60 # https://github.com/rails/rails/commit/deba47799ff905f778e0c98a015789a1327d5087
61 if Rails.env != "test"
62 ActiveRecord::Base.connection.close