1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 require 'current_api_client'
7 module SweepTrashedObjects
8 extend CurrentApiClient
10 def self.delete_project_and_contents(p_uuid)
11 p = Group.find_by_uuid(p_uuid)
12 if !p || p.group_class != 'project'
13 raise "can't sweep group '#{p_uuid}', it may not exist or not be a project"
15 # First delete sub projects
16 Group.where({group_class: 'project', owner_uuid: p_uuid}).each do |sub_project|
17 delete_project_and_contents(sub_project.uuid)
19 # Next, iterate over all tables which have owner_uuid fields, with some
20 # exceptions, and delete records owned by this project
21 skipped_classes = ['Group', 'User']
22 ActiveRecord::Base.descendants.reject(&:abstract_class?).each do |klass|
23 if !skipped_classes.include?(klass.name) && klass.columns.collect(&:name).include?('owner_uuid')
24 klass.where({owner_uuid: p_uuid}).destroy_all
27 # Finally delete the project itself
33 # Sweep trashed collections
35 where('delete_at is not null and delete_at < statement_timestamp()').
38 where('is_trashed = false and trash_at < statement_timestamp()').
39 update_all('is_trashed = true')
41 # Sweep trashed projects and their contents
43 where({group_class: 'project'}).
44 where('delete_at is not null and delete_at < statement_timestamp()').each do |project|
45 delete_project_and_contents(project.uuid)
48 where({group_class: 'project'}).
49 where('is_trashed = false and trash_at < statement_timestamp()').
50 update_all('is_trashed = true')
52 # Sweep expired tokens
53 ActiveRecord::Base.connection.execute("DELETE from api_client_authorizations where expires_at <= statement_timestamp()")
57 def self.sweep_if_stale
58 return if Rails.configuration.trash_sweep_interval <= 0
59 exp = Rails.configuration.trash_sweep_interval.seconds
61 Rails.cache.fetch('SweepTrashedObjects', expires_in: exp) do
66 Thread.current.abort_on_exception = false
70 Rails.logger.error "#{e.class}: #{e}\n#{e.backtrace.join("\n\t")}"
72 ActiveRecord::Base.connection.close