Skip to content

Commit

Permalink
Teach ActiveJob to set configs on itself
Browse files Browse the repository at this point in the history
Previously configs of the form `config.active_job.X` were only forwarded to
`ActiveJob::Base`. This teaches Active Job to set them on `ActiveJob` directly
instead, if the setter exists.

For consistency, this more or less mirrors the way that Active Record does it.

Co-authored-by: Adrianna Chang <adrianna.chang@shopify.com>
Co-authored-by: Sam Bostock <sam.bostock@shopify.com>

---

Fix use_big_decimal_serializer Rails 7.1 default

This config should be enabled for new Rails 7.1 apps, or apps that have updated
their config to `load_defaults 7.1`, not disabled.

This also clarifies the config accessor comment.

---

Add contributor documentation comment to load_defaults

The process for introducing a change in behavior in Rails can be confusing to
new contributors, so a comment is added roughly explaining how to do so, and
what belongs in `load_defaults` and `new_framework_defaults`.

This comment is aimed at contributors, not consumers, so it is added within the
method, rather than above it.
  • Loading branch information
sambostock committed Jul 30, 2022
1 parent 2b3245d commit b4fffc3
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 4 deletions.
2 changes: 1 addition & 1 deletion activejob/lib/active_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module ActiveJob
# :singleton-method:
# If false, Rails will preserve the legacy serialization of BigDecimal job arguments as Strings.
# If true, Rails will use the new BigDecimalSerializer to (de)serialize BigDecimal losslessly.
# This behavior will be removed in Rails 7.2.
# Legacy serialization will be removed in Rails 7.2, along with this config.
singleton_class.attr_accessor :use_big_decimal_serializer
self.use_big_decimal_serializer = false
end
17 changes: 15 additions & 2 deletions activejob/lib/active_job/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,29 @@ class Railtie < Rails::Railtie # :nodoc:
options = app.config.active_job
options.queue_adapter ||= :async

config.after_initialize do
options.each do |k, v|
k = "#{k}="
if ActiveJob.respond_to?(k)
ActiveJob.send(k, v)
end
end
end

ActiveSupport.on_load(:active_job) do
# Configs used in other initializers
options = options.except(
:log_query_tags_around_perform,
:custom_serializers
)

options.each do |k, v|
options.each do |k, v|
k = "#{k}="
send(k, v) if respond_to? k
if ActiveJob.respond_to?(k)
ActiveJob.send(k, v)
elsif respond_to? k
send(k, v)
end
end
end

Expand Down
16 changes: 15 additions & 1 deletion railties/lib/rails/application/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,20 @@ def initialize(*)
# {configuration guide}[https://guides.rubyonrails.org/configuring.html#versioned-default-values]
# for the default values associated with a particular version.
def load_defaults(target_version)
# To introduce a change in behavior, follow these steps:
# 1. Add an accessor on the target object (e.g. the ActiveJob class for global Active Job config).
# 2. Set a default value there preserving existing behavior for existing applications.
# 3. Implement the behavior change based on the config value.
# 4. In the section below corresponding to the next release of Rails, set the new value.
# 5. Add a commented out section in the `new_framework_defaults` template, setting the new value.
# 6. Update the guide in `configuration.md`.

# To remove configurable deprecated behavior, follow these steps:
# 1. Update or remove the entry in the guides.
# 2. Remove the references below.
# 3. Remove the legacy code paths and config check.
# 4. Remove the config accessor.

case target_version.to_s
when "5.0"
if respond_to?(:action_controller)
Expand Down Expand Up @@ -279,7 +293,7 @@ def load_defaults(target_version)
end

if respond_to?(:active_job)
active_job.use_big_decimal_serializer = false
active_job.use_big_decimal_serializer = true
end

if respond_to?(:active_support)
Expand Down
37 changes: 37 additions & 0 deletions railties/test/application/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2656,6 +2656,43 @@ class ::DummySerializer < ActiveJob::Serializers::ObjectSerializer; end
assert_includes ActiveJob::Serializers.serializers, DummySerializer
end

test "use_big_decimal_serializer is enabled in new apps" do
app "development"

# When loaded, ActiveJob::Base triggers the :active_job load hooks, which is where config is attached.
# Referencing the constant auto-loads it.
ActiveJob::Base

assert ActiveJob.use_big_decimal_serializer, "use_big_decimal_serializer should be enabled in new apps"
end

test "use_big_decimal_serializer is disabled if using defaults prior to 7.1" do
remove_from_config '.*config\.load_defaults.*\n'
add_to_config 'config.load_defaults "7.0"'
app "development"

# When loaded, ActiveJob::Base triggers the :active_job load hooks, which is where config is attached.
# Referencing the constant auto-loads it.
ActiveJob::Base

assert_not ActiveJob.use_big_decimal_serializer, "use_big_decimal_serializer should be disabled in defaults prior to 7.1"
end

test "use_big_decimal_serializer can be enabled in config" do
remove_from_config '.*config\.load_defaults.*\n'
add_to_config 'config.load_defaults "7.0"'
app_file "config/initializers/new_framework_defaults_7_1.rb", <<-RUBY
Rails.application.config.active_job.use_big_decimal_serializer = true
RUBY
app "development"

# When loaded, ActiveJob::Base triggers the :active_job load hooks, which is where config is attached.
# Referencing the constant auto-loads it.
ActiveJob::Base

assert ActiveJob.use_big_decimal_serializer, "use_big_decimal_serializer should be enabled if set in config"
end

test "active record job queue is set" do
app "development"

Expand Down

0 comments on commit b4fffc3

Please sign in to comment.