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

Conversation

carbonin
Copy link
Member

@carbonin carbonin commented Jan 5, 2018

This PR adds a new purging mode to the PurgingMixin and uses that new mode for removing orhaned rows from the vim_performance_states table.

Orphan purging is needed when we remove a row from a referenced table, but don't cascade that removal to other tables.

Vm -> VimPerformanceState is one such situation

When a vm is removed the performance states for that vm linger ... forever. This PR fixes that.

https://bugzilla.redhat.com/show_bug.cgi?id=1434918

@carbonin carbonin requested review from kbrock and Fryguy January 5, 2018 17:07
@carbonin carbonin changed the title Add orphan purging for vim_performance_states [WIP] Add orphan purging for vim_performance_states Jan 5, 2018
@carbonin carbonin added the wip label Jan 5, 2018
@carbonin
Copy link
Member Author

carbonin commented Jan 5, 2018

Leaving this as WIP until we can ensure that this is the right direction.

Specifically looking for input from @kbrock on efficiency and @Fryguy for the general layout.

I'm not sure we want to apply this purging to more classes yet as this PR is just really to fix the existing issue with vim_performance_states.

Also, I'm not sure what this would look like if we wanted to do multiple types of purging for a particular model. Maybe we could reimplement #purge_mode_and_value to nest the arrays even more? Something like:

  # In VimPerformanceState::Purging
  def purge_mode_and_value
    [
      ["orphaned", "resource"],
      ["date", 6.months.ago]
    ]
  end

  # In PurgingMixin
  def purge_timer
    purge_mode_and_value.each do |mode, args|
      purge_queue(mode, args)
    end
  end

Either way, it's probably out of the scope of this PR, but I figured it was worth thinking about now.

@carbonin
Copy link
Member Author

carbonin commented Jan 5, 2018

I added some query tracking to the specs to ensure that we won't pull back a ton of data. This is the delete being issued:

DELETE FROM "vim_performance_states"
WHERE "vim_performance_states"."id" IN
  (
    SELECT  "vim_performance_states"."id"
    FROM "vim_performance_states"
    LEFT OUTER JOIN "vms" ON vim_performance_states.resource_id = "vms".id
    WHERE "vms"."id" IS NULL AND "vim_performance_states"."resource_type" = $1 LIMIT $2
  )

Looks good to me ... @kbrock any concerns?

@@ -1200,6 +1203,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.

@@ -55,7 +55,7 @@ def purge_queue(mode, value = nil)
MiqQueue.submit_job(
:class_name => name,
:method_name => "purge_by_#{mode}",
:args => [value]
:args => value.kind_of?(Array) ? value : [value]
Copy link
Member

Choose a reason for hiding this comment

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

Does Array.wrap do this?

@@ -98,8 +98,40 @@ 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, polymorphic, join_table = "", window = purge_window_size)
_log.info("Purging orphans in #{table_name.humanize}...")
total = polymorphic ? purge_polymorphic_orphans(fk_name, window) : purge_orhans(fk_name, join_table, window)
Copy link
Member

Choose a reason for hiding this comment

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

Typo purge_orhans... Need a test to go through this.

total
end

def polymorphic_classes(type_column)
Copy link
Member

Choose a reason for hiding this comment

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

Can we make this variable resource_type_column? Only because type is it's own thing, and it's confusing to read.

Copy link
Member

Choose a reason for hiding this comment

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

Or polymorphic_type_column ?

scope = joins("LEFT OUTER JOIN #{resource_table} ON #{table_name}.resource_id = #{resource_table}.id")
.where(resource_table => {:id => nil})
.where("#{table_name}.#{connection.quote_column_name(type_column)} = #{connection.quote(klass.name)}")
total += purge_in_batches(scope, window)
Copy link
Member

Choose a reason for hiding this comment

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

This might have to support passing a block in the future so you can deal with tools that need to show progress, but I'm fine with passing on that for now.

end

def purge_orphans(fk_name, join_table, window)
raise "Purging non-polymorphic refrences requires a join table name" if join_table.empty?
Copy link
Member

Choose a reason for hiding this comment

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

Typo refrences

@@ -1043,6 +1043,9 @@
:active_task_timeout: 6.hours
:ui:
:mark_translated_strings: false
:vim_performance_state:
Copy link
Member

Choose a reason for hiding this comment

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

state or states? I;m thinking states.

@Fryguy
Copy link
Member

Fryguy commented Jan 8, 2018

As discussed let's remove the non-polymorphic case and just put a comment in the method that it only supports polymorphic for now, since we don't have any use cases for orphaned and non-polymorphic (and thus can't test it either).

@carbonin carbonin changed the title [WIP] Add orphan purging for vim_performance_states Add orphan purging for vim_performance_states Jan 8, 2018
@carbonin carbonin removed the wip label Jan 8, 2018
Copy link
Member

@kbrock kbrock left a comment

Choose a reason for hiding this comment

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

This looks nice.

ASIDE (and unrelated to this PR):
Wish we didn't have to copy and paste so much for the purging.
Seems we should just have 1 purge task.

@@ -1200,6 +1203,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

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.

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}.resource_id = #{resource_table}.id")
Copy link
Member

@kbrock kbrock Jan 11, 2018

Choose a reason for hiding this comment

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

nit: think resource_id may be "#{fk_name}_id?

But to be honest, I almost feel like passing in fk_name is overkill.

I just saw the "#{fk_name}_type" and thought the same pattern should be used for the _id portion. (otherwise if they pass in something other than "resource" I think this will fail.

Copy link
Member Author

Choose a reason for hiding this comment

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

nit: think resource_id may be "#{fk_name}_id? ... I think this will fail.

Yup, good catch. Will change this.


scope = joins("LEFT OUTER JOIN #{resource_table} ON #{table_name}.resource_id = #{resource_table}.id")
.where(resource_table => {:id => nil})
.where("#{table_name}.#{connection.quote_column_name(polymorphic_type_column)} = #{connection.quote(klass.name)}")
Copy link
Member

Choose a reason for hiding this comment

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

can you just do?

where(polymorphic_type_column => klass.name)

Copy link
Member Author

Choose a reason for hiding this comment

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

Brakeman complained about that 😟

end

def polymorphic_classes(polymorphic_type_column)
select(polymorphic_type_column).distinct.pluck(polymorphic_type_column).map(&:constantize)
Copy link
Member

Choose a reason for hiding this comment

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

Think select is not necessary with the pluck.

This method allows for purging by broken polymorphic
references rather than just a timestamp.
This uses the new "orhaned" purging mode to remove rows from
vim_performance_states which have dangling pointers

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1434918
@miq-bot
Copy link
Member

miq-bot commented Jan 15, 2018

Checked commits carbonin/manageiq@e189955~...1c3b2c9 with ruby 2.3.3, rubocop 0.52.0, haml-lint 0.20.0, and yamllint 1.10.0
6 files checked, 1 offense detected

app/models/vim_performance_state/purging.rb

Copy link
Member

@agrare agrare left a comment

Choose a reason for hiding this comment

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

Love the new purge_by_orphaned method 👍

@agrare
Copy link
Member

agrare commented Jan 18, 2018

@gtanzillo what do you think?

@gtanzillo gtanzillo added this to the Sprint 78 Ending Jan 29, 2018 milestone Jan 18, 2018
@gtanzillo gtanzillo merged commit b343ea0 into ManageIQ:master Jan 18, 2018
@carbonin carbonin deleted the add_orphan_purging branch August 16, 2019 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants