Ref: https://bugs.ruby-lang.org/issues/15554
A couple are harmless, but another couple found actual problems
in the test suite where we passed blocks to `assert_*` methods that
didn't expect one.
Fix: https://github.com/rails/rails/pull/51426#issuecomment-2042611790
`perform_later` is supposed to return the Job instance on success,
and `false` on error.
When the `enqueue` is automatically delayed, it's of course impossible
to predict if the actual queueing will succeed, but for backward compatibility
reasons, it's best to assume it will.
If necessary, you can hold onto the job instance and check for
`#successfully_enqueued?` after the transaction has completed.
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>
Since #50715, there are cases where `ActiveJob::Arguments` is used
but not required anymore in the test environment. This could be a
test for a custom argument serializer.
One solution could be to add a require "active_job/arguments" in
all the usages, but that isn't a convention we follow in Rails.
Instead, let's register the autoload for `ActiveJob::Arguments` in
`active_job.rb` so that it's always available when needed.
The following was added to the `ActiveJob::Callbacks`,
`ActiveModel::Callbacks` and `AbstractController:Callbacks` docs
in #29072:
> NOTE: Calling the same callback multiple times will overwrite
> previous callback definitions.
The comment refers to "calling" callbacks but seems to be about defining
callbacks, as mentioned in the PR description.
In the ActiveJob and AbstractController docs, I believe this will be
misinterpreted as referring to setting callbacks, which, as far as I can
tell, does not have such a restriction.
In the ActiveModel docs, I believe it would be slightly clearer to
replace "calling" with "defining".
The Rails documentation uses the `:include:` directive to inline the
README of the framework into the main documentation page. As the
README's aren't in the root directory from where SDoc is run we need to
add the framework path to the include:
# :include: activesupport/README.md
This results in a warning when installing the gems as generating the rdoc for the gem is run from the gem/framework root:
Couldn't find file to include 'activesupport/README.rdoc' from lib/active_support.rb
The `:include:` RDoc directive supports includes relative to the current
file as well:
# :include: ../README.md
This makes sure it works for the Rails API docs and the separate gems.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Now that we dropped support for Ruby 2.7, we no longer
need to check if variables are defined before accessing them
to avoid the undefined variable warning.
ActiveSupport::Deprecation used to `include Singleton` which is why the require is here, but it was removed in 9812641891f1c9ba4c3f8ffb8549ec26fc2668c4 (June 5 2023). Leaving the require seems to have been an oversight.
However, module ActiveJob::Serializers::ObjectSerializer does require Singleton and was relying on AS:Deprecation to require it. This PR just moves the require to the place it's actually used.
https://github.com/rails/rails/pull/50090 broke serialization of String
subclasses that don't have serializers, like ActiveSupport::SafeBuffer.
Co-authored-by: John Hawthorn <john@hawthorn.email>
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)
```
This commit adds an example to the `assert_enqueued_with` method documentation,
demonstrating how to use it with keyword arguments.
The example clarifies that keyword arguments should be specified as a hash inside an array,
providing guidance for developers writing tests for jobs that use keyword arguments.
This is an internal fix, not user facing. I noticed it while working on https://github.com/rails/rails/pull/48585.
The `async` adapter has an `immediate` option, which should only be used in tests. This option should tell the adapter to run jobs inline. This works correctly with `perform_later`, but it does not work with `enqueue_at`, which is what other internal mechanisms such as `retry_job` use.
This PR fixes this bug.