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

Do not commit to db unchanged products in bulk save #12515

Conversation

isidzukuri
Copy link
Contributor

@isidzukuri isidzukuri commented May 24, 2024

What? Why?

It imprves performance.

What should we test?

  • enable feature toggle admin_style_v3
  • Set up a product with invalid tax category (see Show any tax category errors when saving variants #12486 (comment)). This will make the product invalid.
  • visit /admin/products
  • saving of other products should work
    • unchanged invalid product should be ignored, with no error message.
    • saving time may be improved.
    • (in DEV: in logs should be visible db commit transactions only for updated products )

Release notes

Changelog Category (reviewers may add a label for the release notes):

  • User facing changes
  • API changes (V0, V1, DFC or Webhook)
  • Technical changes only
  • Feature toggled

Dependencies

Documentation updates

@dacook dacook force-pushed the 12503_skip_saving_of_unchanged_products branch from 69aa10c to 9ada323 Compare May 27, 2024 00:54
@dacook dacook added the technical changes only These pull requests do not contain user facing changes and are grouped in release notes label May 27, 2024
@dacook dacook marked this pull request as ready for review May 27, 2024 00:59
@dacook
Copy link
Member

dacook commented May 27, 2024

I hope you don't mind me updating this, because I think it is ready for review now :D

@isidzukuri
Copy link
Contributor Author

cool! Thank you! 👍

Copy link
Collaborator

@rioug rioug left a comment

Choose a reason for hiding this comment

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

Nice one, but I think we are missing testing on one of the changes David made (see comment ), could you update the specs ? thanks !

app/models/spree/variant.rb Outdated Show resolved Hide resolved
end

it 'does not increase saved_count' do
subject
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's a bit of a nit pick, but using subject here without knowing the context doesn't tell us what's happening. It'd rather be explicit and use product_set.save so I know straight away what we are testing.
Same for the various use of subject below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I haven't seen anywhere in the project style guide about it. So its comes down to personal preferences. In such cases i follow the betterspecs.org. If talking particularly about subject a lot arguments are here betterspecs/betterspecs#7

I understand that exist different styles of writing tests. Another one is to put all context definition into into each it. Its described in book "Testing Rails"(Josh Steiner, Joël Quenneville) https://books.thoughtbot.com/assets/testing-rails.pdf . But it does not looks like OFN follows this approach either.

but using subject here without knowing the context doesn't tell us what's happening

Sounds like a code smell. Why? Because subject describes what tested subject actually does. And its good when it does only one thing, because of Single Responsibility principle (SOLID). From my experience: If its not possible to write simple, obvious unit tests using rspec interface - code design is not optimal. Is the class ProductSet really that bad? Well, it uses inheritance, method override. include, extend, metaprogramming.... and it makes it sophistiated. But still its possible to make assumption that main(!) responsibility is to persist some data, and it is described here:

RSpec.describe Sets::ProductSet do
describe '#save' do
let(:product_set) do
described_class.new(collection_attributes: collection_hash)
end
subject{ product_set.save }

It follows rspec convention. So its good enough for me at the moment as for legacy code.

For context definition exists keyword context. Maybe it worth to extend description at this line https://github.com/openfoodfoundation/openfoodnetwork/pull/12515/files#diff-385c5ce991f97a247a8510a960775290559a04d5f0f4007219bdd346db00cc8eR138 to make it more obvious?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or the spec can also look like:

expect {subject}.not_to change { product_set.saved_count }.from( 0 )

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I should have expressed myself better, it's more of a "personal nit pick". I am aware of the better spec recommendations, I just don't agree with all of it. But as you say it comes down to personal preference.
Anyway I am happy for the code to be merged like this, the requested change was in relation to David's changes, which he updated. So all good now !

@dacook dacook force-pushed the 12503_skip_saving_of_unchanged_products branch from 9ada323 to 397d778 Compare May 28, 2024 01:55
Price is actually an association with lots of custom methods to make it look like a field, and so changes were ignored.
Now this issue is fixed, perhaps it should be moved to a concern..

Note, there are other delegated fields: product name and description may be assigned from the variant. But there's no hooks to save the prroduct, so I didn't include it when checking for changes.
@dacook dacook force-pushed the 12503_skip_saving_of_unchanged_products branch from 397d778 to 90c71c6 Compare May 28, 2024 02:12
Copy link
Collaborator

@rioug rioug left a comment

Choose a reason for hiding this comment

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

Thanks for your help @isidzukuri ! The PR looks good now.

app/models/spree/variant.rb Outdated Show resolved Hide resolved
end

it 'does not increase saved_count' do
subject
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I should have expressed myself better, it's more of a "personal nit pick". I am aware of the better spec recommendations, I just don't agree with all of it. But as you say it comes down to personal preference.
Anyway I am happy for the code to be merged like this, the requested change was in relation to David's changes, which he updated. So all good now !

[skip ci]
@dacook dacook requested a review from mkllnk May 29, 2024 00:56
Copy link
Member

@mkllnk mkllnk left a comment

Choose a reason for hiding this comment

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

Nice to see this collaboration. It's not easy to work on legacy code. Well done.

@filipefurtad0 filipefurtad0 self-assigned this Jun 5, 2024
@filipefurtad0 filipefurtad0 added the pr-staged-fr staging.coopcircuits.fr label Jun 5, 2024
@filipefurtad0
Copy link
Contributor

Hey @isidzukuri ,

Thanks for working on this. I've followed your steps, and looked at the console. I think I've spotted the DB transaction for the non-updated product as well:

image

In any case, the PR seems not to introduce any regression. I'm just not sure it is bringing the expected improvement. What do you think?

@filipefurtad0 filipefurtad0 added feedback-needed and removed pr-staged-fr staging.coopcircuits.fr labels Jun 5, 2024
@isidzukuri
Copy link
Contributor Author

isidzukuri commented Jun 5, 2024

hi @filipefurtad0 ! Thank you for checking!
This line of log is related to all parameters sent from UI to rails controller. Logs of queries to DB looks slightly different. For example:

Article Load (0.2ms)  SELECT "articles".* FROM "articles" /*application='Blog',controller='articles',action='index'*/
Article Update (0.3ms)  UPDATE "articles" SET "title" = ?, "updated_at" = ? WHERE "posts"."id" = ? /*application='Blog',job='ImproveTitleJob'*/  [["title", "Improved Rails debugging guide"], ["updated_at", "2022-10-16 20:25:40.091371"], ["id", 1]]

It should include SQL statements like UPDATE, CREATE, SELECT...
I don't see any at this screenshot. So it looks as expected to me.

Additional info is here:

@filipefurtad0 filipefurtad0 added pr-staged-fr staging.coopcircuits.fr and removed feedback-needed labels Jun 5, 2024
@filipefurtad0
Copy link
Contributor

Hey @isidzukuri :-)

Thank you so much for your your help!

(in DEV: in logs should be visible db commit transactions only for updated products )

Shouldn't we be seeing that UPDATE line on updated product?

I was thinking one reason for not seeing it, could be that we'd have to enable this option (according to the documentation you've sent):

config.active_record.query_log_tags_enabled = true

I've tried adding it to /config/application.rb and restarting both the server and the puma service, but still no luck.

What do you think? Thanks again for your help 🙏

@filipefurtad0 filipefurtad0 removed the pr-staged-fr staging.coopcircuits.fr label Jun 5, 2024
@isidzukuri
Copy link
Contributor Author

@filipefurtad0 On valid updated product - yes, log should be visible. I saw it locally, in development environment, with default settings. It looks like:
screen11

@isidzukuri
Copy link
Contributor Author

in other environments this log may be disabled. If so, to check if product was updated i can see two options: enable logging or check updated_at column.

@filipefurtad0
Copy link
Contributor

Yes, indeed this type of log seems to be disabled. I was not able to set it up, so I was not able to check this type of commits. However...

check updated_at column

This is indeed a great idea! Thank you 👍

image

So we can see that, despite the invalid new variant, the existing variant is edited (updated_at changes), but no new variant is created (variant count stays the same).

Alright, merging!

@filipefurtad0 filipefurtad0 merged commit 5872515 into openfoodfoundation:master Jun 5, 2024
6 checks passed
@isidzukuri
Copy link
Contributor Author

@filipefurtad0 great 🚀

PS: may be useful for the future, log should be enabled by adding ActiveRecord::Base.logger.level = :debug somewhere in the code before query execution, for example to /config/application.rb as you wrote previously

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
technical changes only These pull requests do not contain user facing changes and are grouped in release notes
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[BUU] Avoid validating all records when saving
5 participants