Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add orphan purging for vim_performance_states #16754

Merged
merged 4 commits into from
Jan 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/models/miq_schedule_worker/jobs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ def binary_blob_purge_timer
queue_work(:class_name => "BinaryBlob", :method_name => "purge_timer", :zone => nil)
end

def vim_performance_states_purge_timer
queue_work(:class_name => "VimPerformanceState", :method_name => "purge_timer", :zone => nil)
end

def miq_schedule_queue_scheduled_work(schedule_id, rufus_job)
MiqSchedule.queue_scheduled_work(schedule_id, rufus_job.job_id, rufus_job.next_time.to_i, rufus_job.opts)
end
Expand Down
5 changes: 5 additions & 0 deletions app/models/miq_schedule_worker/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ def schedules_for_scheduler_role
enqueue(:binary_blob_purge_timer)
end

every = worker_settings[:vim_performance_states_purge_interval]
scheduler.schedule_every(every, :first_in => every) do
enqueue(:vim_performance_states_purge_timer)
end

# Schedule every 24 hours
at = worker_settings[:storage_file_collection_time_utc]
if Time.now.strftime("%Y-%m-%d #{at}").to_time(:utc) < Time.now.utc
Expand Down
29 changes: 29 additions & 0 deletions app/models/mixins/purging_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,37 @@ def purge_by_scope(older_than = nil, window = nil, &block)
_log.info("Purging #{table_name.humanize}...Complete - Deleted #{total} records")
end

def purge_by_orphaned(fk_name, window = purge_window_size)
_log.info("Purging orphans in #{table_name.humanize}...")
total = purge_orphans(fk_name, window)
_log.info("Purging orphans in #{table_name.humanize}...Complete - Deleted #{total} records")
total
end

private

def purge_orphans(fk_name, window)
# For now, this only supports polymorphic references
# We don't currently have a situation where a table with a regular reference needs to be purged
polymorphic_type_column = "#{fk_name}_type"
polymorphic_id_column = connection.quote_column_name("#{fk_name}_id")
total = 0

polymorphic_classes(polymorphic_type_column).each do |klass|
resource_table = connection.quote_table_name(klass.table_name)

scope = joins("LEFT OUTER JOIN #{resource_table} ON #{table_name}.#{polymorphic_id_column} = #{resource_table}.id")
.where(resource_table => {:id => nil})
.where("#{table_name}.#{connection.quote_column_name(polymorphic_type_column)} = #{connection.quote(klass.name)}")
total += purge_in_batches(scope, window)
end
total
end

def polymorphic_classes(polymorphic_type_column)
distinct(polymorphic_type_column).pluck(polymorphic_type_column).map(&:constantize)
end

# Private: The ids to purge if we want to keep a fixed number of records
# for each resource. Newer records (with a higher id/ lower rank) are kept.
#
Expand Down
2 changes: 2 additions & 0 deletions app/models/vim_performance_state.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class VimPerformanceState < ApplicationRecord
include_concern 'Purging'

serialize :state_data

belongs_to :resource, :polymorphic => true
Expand Down
16 changes: 16 additions & 0 deletions app/models/vim_performance_state/purging.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class VimPerformanceState < ApplicationRecord
module Purging
extend ActiveSupport::Concern
include PurgingMixin

module ClassMethods
def purge_mode_and_value
%w(orphaned resource)
end

def purge_window_size
::Settings.vim_performance_states.history.purge_window_size
end
end
end
end
4 changes: 4 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,9 @@
:active_task_timeout: 6.hours
:ui:
:mark_translated_strings: false
:vim_performance_states:
:history:
:purge_window_size: 1000
:webservices:
:consume_protocol: https
:contactwith: ipaddress
Expand Down Expand Up @@ -1206,6 +1209,7 @@
:storage_file_collection_interval: 1.days
:storage_file_collection_time_utc: 21600
:task_timeout_check_frequency: 1.hour
:vim_performance_states_purge_interval: 1.day
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this seem like a good value?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought we'd do something closer to 6 month. but I not know the usage of this table.

:vm_retired_interval: 10.minutes
:yum_update_check: 12.hours
:ui_worker:
Expand Down
37 changes: 37 additions & 0 deletions spec/models/vim_performance_state/purging_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
describe VimPerformanceState do
context "::Purging" do
describe ".purge_by_orphaned" do
it "purges all the orphaned rows for all referenced classes" do
# Create an orphaned row referencing VmOrTemplate
vm1 = FactoryGirl.create(:vm_or_template)
vm_perf1 = FactoryGirl.create(:vim_performance_state, :resource => vm1)
vm1.delete

# Create a non-orphaned row referencing VmOrTemplate
vm_perf2 = FactoryGirl.create(:vim_performance_state, :resource => FactoryGirl.create(:vm_or_template))

# Create an orphaned row referencing ExtManagementSystem
ems1 = FactoryGirl.create(:ext_management_system)
ems_perf1 = FactoryGirl.create(:vim_performance_state, :resource => ems1)
ems1.delete

# Create a non-orphaned row referencing ExtManagementSystem
ems_perf2 = FactoryGirl.create(:vim_performance_state, :resource => FactoryGirl.create(:ext_management_system))

expect(described_class.all).to match_array([vm_perf1, vm_perf2, ems_perf1, ems_perf2])
count = described_class.purge_by_orphaned("resource")
expect(described_class.all).to match_array([vm_perf2, ems_perf2])
expect(count).to eq(2)
end
end

describe ".purge_timer" do
it "queues the correct purge method" do
EvmSpecHelper.local_miq_server
described_class.purge_timer
q = MiqQueue.first
expect(q).to have_attributes(:class_name => described_class.name, :method_name => "purge_by_orphaned", :args => ["resource"])
end
end
end
end