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

[AuthenticationMixin] authentication_status to virtual_delegate #18196

Conversation

NickLaMuro
Copy link
Member

@NickLaMuro NickLaMuro commented Nov 14, 2018

Creates a virtual_delegate for AuthenticationMixin#authentication_status which allows it to be included in reports and put in as part of the main query.

The biggest thing of note in this change is how the status_severity_arel is being used to handle the sorting properly in the SQL query. It makes use of a SQL's case statement to handle what would normally be a sort_by on the hash lookup of Authentication::STATUS_SEVERITY. Instead, we match each key to the status column and use that as the value for the ORDER BY exp DESC in the has_one, which allows for the same affect.

This also means that it can inject itself in the SELECT of a MiqReport, and avoid N+1's on things like quadicons and such for pages that use MiqReport#paged_view_search.

Metrics

An example set of runs I had with a 47 Host provider:

Before

/ems_infra/report_data

ms queries query (ms) rows
2993 154 1853.6 3644
2471 154 1759.1 3644
1869 154 1780.7 3644

After

/ems_infra/report_data

ms queries query (ms) rows
2453 107 1588.7 3582
2420 107 1640.3 3582
2736 107 1603.0 3582

Links

Steps for Testing/QA

Here is a script to generate test data that I was using:

https://gist.github.com/NickLaMuro/225833358423723ed17ff294415fa6b4

For testing, I did the following:

  • Seed with the above script from manageiq: bin/rails r bz_1580569_db_replication_script.rb
  • Spin up a server: bin/rails s
  • Do the following in a browser:
    • Login
    • Navigate to Compute -> Infrastructure -> Providers in the side menu
    • Up the per_page to 1k (just to load all of the records in a single page
    • Select a provider (one with the most Host records, ideally)
    • Select the Hosts button

Between master, and this change, you should see the number of queries per request for the last portion in the above drop by the number of Host records for that provider. The Metrics section above used this process.

@miq-bot miq-bot added the wip label Nov 14, 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.

Is this really a WIP?

@@ -4,7 +4,16 @@ module AuthenticationMixin
included do
has_many :authentications, :as => :resource, :dependent => :destroy, :autosave => true

virtual_column :authentication_status, :type => :string
has_one :authentication_status_severity_level,
Copy link
Member

Choose a reason for hiding this comment

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

<3

app/models/authentication.rb Outdated Show resolved Hide resolved
app/models/mixins/authentication_mixin.rb Outdated Show resolved Hide resolved
NickLaMuro added a commit to NickLaMuro/manageiq-ui-classic that referenced this pull request Nov 14, 2018
This is related to changes in:

  ManageIQ/manageiq#18196

When `authentication_status` is changed to a `virtual_delegate`, we are
able to pre-fetch the values as part of the original query, and avoid an
N+1.
@NickLaMuro NickLaMuro changed the title [WIP][AuthenticationMixin] authentication_status to virtual_delegate [AuthenticationMixin] authentication_status to virtual_delegate Nov 15, 2018
@miq-bot miq-bot removed the wip label Nov 15, 2018
@NickLaMuro
Copy link
Member Author

@Fryguy @kbrock Thanks for the suggestions (and reminding me there were review comments). Going to take a few minutes and apply them to this PR.

Creates a virtual_delegate for AuthenticationMixin#authentication_status
which allows it to be included in reports and put in as part of the main
query.

The biggest thing of note in this change is how the status_severity_arel
is being used to handle the sorting properly in the SQL query.  It makes
use of a SQL's case statement to handle what would normally be a
`sort_by` on the hash lookup of Authentication::STATUS_SEVERITY.
Instead, we match each key to the status column and use that as the
value for the `ORDER BY exp DESC` in the `has_one`, which allows for the
same affect.

This also means that it can inject itself in the `SELECT` of a
`MiqReport`, and avoid N+1's on things like quadicons and such for pages
that use `MiqReport#paged_view_search`.
@NickLaMuro NickLaMuro force-pushed the authentication_mixin_authentication_status_to_virtual_delegate branch from e02cf66 to 49d854d Compare November 15, 2018 19:43
@NickLaMuro
Copy link
Member Author

@Fryguy @kbrock Alright, gave it a bit of a tweak, and added some specs. Let me know what you think.

@miq-bot
Copy link
Member

miq-bot commented Nov 15, 2018

Checked commit NickLaMuro@49d854d with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
3 files checked, 0 offenses detected
Everything looks fine. ⭐

expect(host.authentication_status).to eq("None")
end

it "is 'None' when accessed via ruby, but fetched via sql" do
Copy link
Member Author

@NickLaMuro NickLaMuro Nov 15, 2018

Choose a reason for hiding this comment

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

Worth noting: This spec and the one above have a important distinction to make here since it is slightly confusing when looking at the result that is provided by virtual_column_sql_value. The default value of "None" is desired here as we want to maintain the previous functionality when calling authentication_status.

@kbrock
Copy link
Member

kbrock commented Nov 16, 2018

sporadic failure strikes again - just kicked one travis job

#
STATUS_SEVERITY_AREL = Arel::Nodes::Case.new.tap do |arel_case|
STATUS_SEVERITY.each do |value, sort_weight|
arel_case.when(arel_table[:status].lower.eq(value)).then(sort_weight)
Copy link
Member

Choose a reason for hiding this comment

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

wow - turns out arel_table[:status] does not access the database.

who knew?

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.

I like these changes.
Will give @Fryguy a little time for comments.
Otherwise I'll merge.

@kbrock kbrock merged commit dd6a3e2 into ManageIQ:master Nov 19, 2018
@kbrock kbrock added this to the Sprint 99 Ending Nov 19, 2018 milestone Nov 19, 2018
@kbrock kbrock self-assigned this Nov 19, 2018
NickLaMuro added a commit to NickLaMuro/manageiq-ui-classic that referenced this pull request Nov 20, 2018
This is related to changes in:

  ManageIQ/manageiq#18196

When `authentication_status` is changed to a `virtual_delegate`, we are
able to pre-fetch the values as part of the original query, and avoid an
N+1.
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.

4 participants