-
Notifications
You must be signed in to change notification settings - Fork 21.9k
Offer dependent: :destroy_async for associations #40157
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
Offer dependent: :destroy_async for associations #40157
Conversation
0622f67
to
26ce831
Compare
aee646b
to
66c4747
Compare
ee96146
to
c112d8e
Compare
c112d8e
to
f6d41ec
Compare
Sometimes cascading association deletions can cause timeouts due to an IO issue. Perhaps a model has associations that are destroyed on deletion which in turn trigger other deletions and this can continue down a complex tree. Along this tree you may also hit other IO operations. Such deep deletions can lead to server timeouts while awaiting completion and really the user may not notice all the changes on their side immediately making them wait unnecesarially or worse causing a timeout during the operation. We now allow associations supporting the `dependent:` key to take `:destroy_async`, which schedules a background job to destroy associations. Co-authored-by: Adrianna Chang <adrianna.chang@shopify.com> Co-authored-by: Rafael Mendonça França <rafael@franca.dev> Co-authored-by: Cory Gwin @gwincr11 <gwincr11@github.com>
f6d41ec
to
4cf7559
Compare
This is awesome 👍 But just curious: why not use That seems more consistent with other delayed methods: Is there something about the behavior that makes |
valid += [:as, :foreign_type] if options[:as] | ||
valid += [:through, :source, :source_type] if options[:through] | ||
valid += [:ensuring_owner_was] if options[:dependent] == :destroy_async |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it a duplicate with the addition 3 lines above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good catch @vendethiel ! Feel free to open a PR ❤️
@@ -7,14 +7,15 @@ def self.macro | |||
end | |||
|
|||
def self.valid_options(options) | |||
valid = super + [:counter_cache, :join_table, :index_errors] | |||
valid = super + [:counter_cache, :join_table, :index_errors, :ensuring_owner_was] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @vendethiel said, here the key is always included, which invalidates line 13, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @adrianna-chang-shopify said, feel free to open a PR 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here @eugeneius , could you review? @adrianna-chang-shopify
@rafaelfranca @adrianna-chang-shopify I don't want to be a pest 😅 but I think it would be useful for the community to understand why this option is named |
The reason for the different name if because we wanted to keep the For the feature implemented here we don't care if the destroy happen in 1s or in 10 minutes. It just need to happen async, without blocking the current request. So the behavior of |
Motivation: - Now that destroy_async is an option on association, a natural next step seems to be adding this method to standard objects for a more consistent offering. Related Issues: - rails#40157 - rails#36912 Changes: - Add a destroy_async method to persistence. - Add a rail tie to setup the active job configs. - Add a default destroy async job. - Test
Would a PR to add |
@tomrossi7 👍 on And also thanks for this |
Revised version of #36912, #39149
Summary
Allows associations taking the
dependent
key to specifydependent: :destroy_async
, which will enqueue a job to destroy associations asynchronously.cc @rafaelfranca - I've removed
ActiveRecord::Base.destroy_later
from this PR, so it only contains the implementation of the asynchronous association deletion. Will rebase + squash if it looks okay to you.