This commit adds `ActiveRecord.deprecator` and replaces all usages of
`ActiveSupport::Deprecation.warn` in `activerecord/lib` with
`ActiveRecord.deprecator`.
Additionally, this commit adds `ActiveRecord.deprecator` to
`Rails.application.deprecators` so that it can be configured using e.g.
`config.active_support.report_deprecations`.
In https://github.com/rails/rails/pull/45796 I overlooked that
`ActiveRecord::LogSubscriber#sql` wasn't only logging the SQL query
but was also responsible for collecting the `:db_runtime` metric.
Ultimately I think it is cleaner to move this concern to `RuntimeRegistry`.
This adds `:db_runtime` to `perform.active_job` notification payloads,
which is the total time taken by database queries while performing a
job. This value can be used to better understand how a job's time is
spent.
This is similar to the `:db_runtime` value added to
`process_action.action_controller` notification payloads by
`ActiveRecord::Railties::ControllerRuntime`.
Closes#35354.
Co-authored-by: Cory Gwin <gwincr11@github.com>
This allows applications to specify the maximum number of records that
will be destroyed in a single background job by the `dependent:
:destroy_async` association option. By default, the current behavior
will remain the same: when a parent record is destroyed, all dependent
records will be destroyed in a single background job. If the number of
dependent records is greater than this configuration, the records will
be destroyed in multiple background jobs.
At GitHub, we have a custom method for destroying associated records
in the background that we'd like to replace with
`dependent: :destroy_async`. Some associations have a large number of
dependent records, and our infrastructure requires that background jobs
complete quickly, so we limit the maximum number of dependent records
destroyed in a single background job and enqueue additional jobs when
the number of records exceeds that limit.
Motivation:
- A active record rollback could occur while enqueuing a job in this
case the job would enqueue even though the database deletion
rolledback putting things in a funky state. So this adds some
functionality to ensure that deletions are not queued until after
the db transaction has been commited.
Related Issues:
- Sort of related to https://github.com/rails/rails/issues/26045
Changes:
- add some syntatic sugar to transactions to make enqueueing a job a
little better experience, this really hooks into the after destroy
hook on the transaction.
- Setup async destroy on associations to not enqueue until after a
transaction has been committed.
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>