Commit Graph

183 Commits

Author SHA1 Message Date
Rafael Mendonça França bf59d363fb
Clean CHANGELOG for 8.0 2024-05-13 16:55:52 +00:00
Rafael Mendonça França 37fd0e7fe4
Development of Rails 8.0 starts now
🎉
2024-05-13 16:45:20 +00:00
Alex Ghiculescu 2194a738c7 Active Job: Correctly use the desired test adapter in tests 2024-05-09 17:35:50 +10:00
Carlos Antonio da Silva 8ad19d9865 Minor tweaks / improvements to recent changelog/api docs [ci skip] 2024-04-08 14:48:44 -03:00
Petrik 52f37c4d81 Update `enqueue_after_transaction_commit` changelog [ci-skip]
The config option accepts `:never`, `:always` and `:default`.
2024-04-05 21:26:28 +02:00
Jean Boussier e922c59207 Implement Active Job enqueue_after_transaction_commit
A fairly common mistake with Rails is to enqueue a job from inside a
transaction, with a record as argumemnt, which then lead to a RecordNotFound
error when picked up by the queue.

This is even one of the arguments advanced for job runners backed by the
database such as `solid_queue`, `delayed_job` or `good_job`.

But relying on this is undesirable in my opinion as it makes the Active Job
abstraction leaky, and if in the future you need to migrate to another backend
or even just move the queue to a separate database, you may experience a lot of
race conditions of the sort.

To resolve this problem globally, we can make Active Job optionally transaction
aware, and automatically defer job queueing to `after_commit`.

Co-Authored-By: Cristian Bica <cristian.bica@gmail.com>
2024-04-03 16:32:16 +02:00
maximerety f72d2118fe
[Fix #50713] Do not trigger loading of ActiveJob::Base in ActiveJob::TestHelper 2024-01-11 19:52:47 +01:00
Joshua Young 18098ccc4c [Fix #50230] Preserve serialized timezone when deserializing with `ActiveJob::Serializers::TimeWithZoneSerializer` 2023-12-03 00:37:09 +10:00
Rafael Mendonça França 03dae98092
Remove deprecated `:exponentially_longer` value for the `:wait` in `retry_on` 2023-11-22 22:13:59 +00:00
Rafael Mendonça França 798289699d
Remove deprecated support to set numeric values to `scheduled_at` attribute 2023-11-22 22:13:06 +00:00
Rafael Mendonça França 2a761d23d2
Remove deprecated primitive serializer for `BigDecimal` arguments 2023-11-22 22:13:03 +00:00
Rafael Mendonça França fb6c6007d0
Development of Rails 7.2 starts now
🎉
2023-09-27 03:59:11 +00:00
Rafael Mendonça França e5386cb402
Preparing for 7.1.0.rc1 release 2023-09-27 03:08:31 +00:00
Ben Sheldon [he/him] c919b474a7
Set, serialize, and deserialize Active Job `scheduled_at` as Time; deserialize `enqueued_at` as Time; deprecate setting `scheduled_at=` with numeric/epoch
Co-authored-by: Adam Pahlevi <adam.pahlevi@gmail.com>
2023-09-26 17:01:41 -07:00
Victor Mours 1bdabc1102 Clarify that the default retry strategy uses polynomial backoff and not exponential backoff 2023-09-16 00:51:14 +02:00
Rafael Mendonça França 699dfdb426
Preparing for 7.1.0.beta1 release 2023-09-13 00:36:01 +00:00
Akhil G Krishnan 61a9c1a92a Ruby code block indentation issue fix
[skip ci] indentation fix

[skip ci] review changes added

[skip ci] indentation fix
2023-09-07 01:14:48 +05:30
Ben Sheldon b1b7debaa3
Fix Active Job log message to correctly report a job failed to enqueue when the adapter raises an `ActiveJob::EnqueueError` 2023-09-02 07:52:43 -07:00
Rafael Mendonça França 53a3a95d01
Merge PR #48010 2023-08-21 17:39:03 +00:00
Jonathan del Strother 074d431493
Fix invalid durations in ActiveJob serialization
Durations that were round-tripped through ActiveJob::Arguments.serialize
would appear fine at a first glance, but trying to perform
duration-math on them would fail:

```
irb(main):001:0> d = ActiveJob::Arguments.deserialize(ActiveJob::Arguments.serialize([1.year]))[0]
=> 1 year
irb(main):002:0> d + 1.day
activesupport-6.1.4.4/lib/active_support/duration.rb:242:in `+': undefined method `merge' for [[:years, 1]]:Array (NoMethodError)
```
2023-08-13 11:27:16 +01:00
Alex Ghiculescu ba70a5be86 Make `perform_enqueued_jobs` compatible with all Active Job adapters 2023-06-28 20:08:08 +10:00
Vipul A M 5c5b78dfa7
Fix a few typos in changelogs [ci skip] (#48573) 2023-06-25 14:56:20 +05:30
Rob Cardy 659d41110f
This method lets job authors define a block which will be run when a job is about to be discarded.
This has utility for gems/modules included on jobs, which can tie into this behaviour and run something when a job fails.
after_discard respects the existing retry behaviour, but will run even if a retried exception is handled in a block.
2023-05-08 14:28:42 -04:00
Sander Verdonschot 6daba18791
Allow queue adapters to provide a custom name
This gives queue adapters more freedom to name and organize their code.

For example, if `FancyQueue` wants to have their adapter at
`FancyQueue::ActiveJobAdapter`, the name would be `active_job` before this
change. After this change, they can implement `queue_adapter_name` to return
`fancy_queue`.
2023-04-20 13:23:50 -04:00
fatkodima f6d56fed27 Add support for logging background job enqueue callers 2023-04-02 03:23:42 +03:00
Cameron Matheson 0cb0880b1a implement `provider_job_id` for Backburner jobs 2023-03-23 19:19:34 -06:00
Sander Verdonschot 9b62f88a2f
Add `perform_all_later` to enqueue multiple jobs at once
Sidekiq has a useful optimisation called `push_bulk` that enqueues many jobs at
once, eliminating the repeated Redis roundtrips. However, this feature is not
exposed through Active Job, so it only works for `Sidekiq::Worker` jobs. This
adds a barrier to Active Job adoption for apps that rely on this feature. It
also makes it harder for other queue adapters to implement similar
functionality, as they then have to take care of serialization, callbacks, etc.
themselves.

This commit adds `ActiveJob.perform_all_later(<job1>, <job2>)`, backed by
Sidekiq's `push_bulk` and with a fallback to enqueuing serially if the queue
adapter does not support bulk enqueue.

The performance benefit for 1000 jobs can be more than an order of magnitude:

| Enqueue type       | Serial time (ms) | Bulk time (ms) | Speedup |
| ------------------ | ---------------- | -------------- | ------- |
| Raw Sidekiq        |             2661 |            119 |     22x |
| Active Job Sidekiq |             2853 |            208 |     14x |

(Measured in a simple test app in our production environment.)

Instrumentation for perform_all_later uses a new event `enqueue_all.active_job`
2023-02-02 16:39:22 -05:00
Alex Ghiculescu f737b5ec13 Fix double logging in `ActiveRecord::QueryLog`
Fixes https://github.com/rails/rails/issues/46103

An issue exists if you set `config.active_record.query_log_tags` to an array that includes `:controller`, `:action`, or `:job`; the relevant item will get duplicated in the log line. This occured because the relevant railties would add the item to `config.active_record.query_log_tags` again during setup. This PR fixes that by only adding those items to the config if they aren't already set.

The issue proposed more documentation to work around this, but I think it's a bug and should be fixed directly.
2022-10-22 15:53:14 -05:00
Jonathan del Strother b38992038f
Use a higher-level Sidekiq API for ActiveJob
This allows Sidekiq to use a custom client_class (rather than
Sidekiq::Client), which is necessary for the new transaction-aware
client in 6.5 (https://github.com/mperham/sidekiq/blob/main/Changes.md#650)
2022-09-20 13:14:24 +01:00
Yasuo Honda cb22eb2b36 Remove QueAdapter from Active Job
Que and Rails (Active Job QueAdapter) have applied changes each other
to support Ruby 3 keyword arguments and options provided as top level keywords, etc
via these commits:

https://github.com/rails/rails/pull/44734
https://github.com/rails/rails/pull/44248
d9244b9074 via https://github.com/que-rb/que/pull/319

Finally, we've found it is quite difficult to maintain them.
Going forward Active Job Que adapter can be included in the future version of que gem itself.
Refer to https://github.com/rails/rails/issues/45899 the background for this change.

Active Job Que adapter can be included in the future version of que gem itself.
2022-09-12 22:31:10 +09:00
Ryuta Kamizono e0e64e9474 Fix typo in activejob/CHANGELOG.md [ci-skip] 2022-08-29 15:34:01 +09:00
Sam Bostock bc1f323338
Add ActiveJob::Serializers::BigDecimalSerializer
Previously, BigDecimal was listed as not needing a serializer.  However,
when used with an adapter storing the job arguments as JSON, it would get
serialized as a simple String, resulting in deserialization also producing
a String (instead of a BigDecimal).

By using a serializer, we ensure the round trip is safe.

During upgrade deployments of applications with multiple replicas making use of
BigDecimal job arguments with a queue adapter serializing to JSON, there exists
a possible race condition, whereby a "new" replica enqueues a job with an
argument serialized using `BigDecimalSerializer`, and an "old" replica fails to
deserialize it (as it does not have `BigDecimalSerializer`).

Therefore, to ensure safe upgrades, serialization will not use
`BigDecimalSerializer` until `config.active_job.use_big_decimal_serializer` is
enabled, which can be done safely after successful deployment of Rails 7.1.

This option will be removed in Rails 7.2, when it will become the default.
2022-07-19 15:31:41 -04:00
Jeremy Daer 8d9d8013ca Preserve `job.enqueued_at` timestamp precision
* Allows instrumenters to more accurately deduce queue wait time
* Retains IS08601 compatibility

References #39698
2022-07-12 18:13:16 -07:00
Gannon McGibbon 02444d9267 Add `--parent` option to job generator to specify parent class of job.
Example:

`bin/rails g job process_payment --parent=payment_job` generates:

```ruby
class ProcessPaymentJob < PaymentJob
  # ...
end
```
2022-07-05 20:55:38 -04:00
Gannon McGibbon 5f57c7d352 Add more detailed description to job generator 2022-06-13 14:44:28 -05:00
Gannon McGibbon 3dad2919d5 Rename behaviour to behavior in documentation 2022-05-26 17:14:18 -04:00
Jonathan Hefner 9574a39a7a Add db_runtime to Active Job instrumentation
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>
2022-05-19 14:09:21 -05:00
Damir Zekić c7b4a8b4ba Update CHANGELOG 2022-03-21 13:43:11 +01:00
Jean Boussier 4ca5aff9f0 Add missing `bigdecimal` require in `ActiveJob::Arguments`
Fix: https://github.com/rails/rails/issues/44399

Could cause `uninitialized constant ActiveJob::Arguments::BigDecimal (NameError)`
when loading Active Job in isolation.
2022-02-12 09:54:41 +01:00
Rafael Mendonça França 6fb54c00e4
Merge PR #43066 2022-01-06 16:53:31 +00:00
Rafael Mendonça França 83d85b2207
Start Rails 7.1 development 2021-12-07 15:52:30 +00:00
Rafael Mendonça França 7c788e9175
Remove deprecated `:return_false_on_aborted_enqueue` option 2021-11-19 23:15:58 +00:00
Rafael Mendonça França 10bd5e59c3
Removed deprecated behavior that was not halting `after_enqueue`/`after_perform` callbacks when a previous callback was halted with `throw :abort`. 2021-11-17 21:51:17 +00:00
Veerpal Brar 0f259e702d Raise error when serializing an anonymous class.
The ModuleSerializer does not support serializing anonymous classes
because when we try to deserialize the anonymous class, it wouldn't
know which class to use (since class name is nil).

For this reason, ModuleSerialzier now raises an error if the class
name is nil. Previously, ModuleSerializer would raise an `undefined
method `constantize' for nil:NilClass` error during deserialization.
It's not clear why the deserialization failed from the error.

In this commit, we raise an explicit error when trying to serialize
an anonymous class indicating this behaviour is not supported.
2021-10-13 11:55:23 -04:00
Rafael Mendonça França d177551c30
Preparing for 7.0.0.alpha2 release 2021-09-15 18:22:51 -04:00
Rafael Mendonça França 9b7be48212
Preparing for 7.0.0.alpha1 release 2021-09-15 17:55:08 -04:00
Jacopo 20545fc820 Allow testing `discard_on/retry_on ActiveJob::DeserializationError`
Previously in `perform_enqueued_jobs`, `deserialize_arguments_if_needed`
was called before calling `perform_now`. When a record no longer exists
and is serialized using GlobalID this led to raising
an `ActiveJob::DeserializationError` before reaching `perform_now` call.
This behaviour makes difficult testing the job `discard_on/retry_on` logic.

Now `deserialize_arguments_if_needed` call is postponed to when `perform_now`
is called.

Example:

```ruby
class UpdateUserJob < ActiveJob::Base
  discard_on ActiveJob::DeserializationError

  def perform(user)
    # ...
  end
end

User.destroy_all
assert_nothing_raised do
  perform_enqueued_jobs only: UpdateUserJob
end
assert_no_enqueued_jobs
```

Before this changes the test will fail, now it passes.
2021-08-23 21:16:56 +02:00
Daniel Morton 94ccd5410d
`retry_on` parameter `attempts` now accepts `:unlimited` (#41761)
In some applications, some classes of errors may be raised during the
execution of a job which the developer would want to retry forever.

These classes of errors would most likely be infrastructure problems that
the developer knows will be resolved eventually but may take a variable
amount of time or errors where due to application business logic, there
could be something temporarily blocking the job from executing, like a
resource that is needed for the job being locked for a lengthy amount of
time.

While an arbitrarily large number of attempts could previously be passed,
this is inexpressive as sometimes the developer may just need the job to
continue to be retried until it eventually succeeds. Without this,
developers would need to include additional code to handle the situation
where the job eventually fails its attempts limit and has to be re-enqueued
manually.

As with many things this should be used with caution and only for errors
that the developer knows will definitely eventually be resolved, allowing
the job to continue.

[Daniel Morton + Rafael Mendonça França]
2021-07-28 18:32:19 -04:00
Ryuta Kamizono e50b0e3ab3 Fixup CHANGELOGs [ci skip] 2021-07-21 10:08:08 +09:00
Wojciech Wnętrzak e2db5f205a
Added possibility to check on `:priority` in test helper methods 2021-07-15 07:46:21 +02:00