Skip to content
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

Load configured Active Storage plugins during boot #45100

Merged
merged 1 commit into from
Jan 7, 2025

Conversation

skipkayhil
Copy link
Member

Summary

Previously, the parts of Active Storage using ruby-vips, mini_magick, or
image_processing would try to load gems only when used. This strategy works
well because it allows apps that don't need these features to easily
ignore them and not have to depend on gems they don't need.

However, the downsides to this strategy are that it requires loading
code during requests and that it moves potential error messages into request
logs instead of those errors being immediately visible on boot.

This commit addresses these issues by restructing how the Vips and Image
Magick transformers/analyzers are organized so that they will be loaded
(if configured) on boot along with whatever dependencies they need.

For now, if :vips or :mini_magick is specified as the Active Storage
:variant_processor, not having the required gem in the Gemfile will print a
deprecation warning instead of erroring because it is likely many apps
are currently configured this way.

Other Information

Looking for feedback on the approach, I will add tests/docs/changelog etc. after

Closes #44991
cc @byroot because of our discussion in the other issue

@skipkayhil skipkayhil force-pushed the load-as-gems-in-initializer branch from 7efa39d to 1859dc9 Compare May 14, 2022 23:02
Copy link
Member

@byroot byroot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of smaller comments, but looks mostly good to me.

@@ -46,6 +46,8 @@ module ActiveStorage
mattr_accessor :verifier
mattr_accessor :variant_processor, default: :mini_magick

mattr_accessor :variant_transformer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: we should probably convert all these mattr_accessor to attr_accessor.

Setting config.active_storage.variant_processor to :mini_magick without adding
mini_magick to the Gemfile is deprecated and will raise in Rails 7.2.

To fix this warning, set config.active_storage.variant_processor = :nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:nil is weird, did you mean nil?

Setting config.active_storage.variant_processor to :vips without adding
ruby-vips to the Gemfile is deprecated and will raise in Rails 7.2.

To fix this warning, set config.active_storage.variant_processor = :nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

def validate_transformation(name, argument)
method_name = name.to_s.tr("-", "_")

unless ActiveStorage.supported_image_processing_methods.any? { |method| method_name == method }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you just moved it over, but I wonder why this isn't just:

Suggested change
unless ActiveStorage.supported_image_processing_methods.any? { |method| method_name == method }
unless ActiveStorage.supported_image_processing_methods.include?(method_name)


unless ActiveStorage.supported_image_processing_methods.any? { |method| method_name == method }
raise UnsupportedImageProcessingMethod, <<~ERROR.squish
One or more of the provided transformation methods is not supported.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When writing error message, it's best to include the faulty value.

ActiveStorage::Transformers::Vips
when :mini_magick
ActiveStorage::Transformers::ImageMagick
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to have an else that raises if the argument wasn't any of the two, this way if someone typo :mini_magick into say :minimagick, they get an early error.

@byroot
Copy link
Member

byroot commented Nov 16, 2024

Hum, this has fallen through the cracks because I don't have push notifications. I think we should do it though. I'll try to find time to rebase this (but I don't even think we need a deprecation here)

Previously, the parts of Active Storage using ruby-vips, mini_magick, or
image_processing would try to load gems only when used. This strategy works
well because it allows apps that don't need these features to easily
ignore them and not have to depend on gems they don't need.

However, the downsides to this strategy are that it requires loading
code during requests and that it moves potential error messages into request
logs instead of those errors being immediately visible on boot.

This commit addresses these issues by restructing how the Vips and Image
Magick transformers/analyzers are organized so that they will be loaded
(if configured) on boot along with whatever dependencies they need.

For now, if :vips or :mini_magick is specified as the Active Storage
:variant_processor, not having the required gem in the Gemfile will print a
deprecation warning instead of erroring because it is likely many apps
are currently configured this way.
@zzak zzak force-pushed the load-as-gems-in-initializer branch from 7c8e351 to 684e760 Compare January 7, 2025 11:40
@rails-bot rails-bot bot added the railties label Jan 7, 2025
@zzak zzak requested a review from byroot January 7, 2025 11:49
@zzak
Copy link
Member

zzak commented Jan 7, 2025

I think this is ready for another look, gave it a rebase and addressed some of the comments.

@rafaelfranca rafaelfranca merged commit e978ef0 into rails:main Jan 7, 2025
3 checks passed
begin
gem "mini_magick"
rescue LoadError => error
raise error unless error.message.include?("ruby-vips")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy-paste error? I think this will cause it to not show the deprecation warning.

Suggested change
raise error unless error.message.include?("ruby-vips")
raise error unless error.message.include?("mini_magick")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 Thanks, was fixing a rubocop failure

@skipkayhil skipkayhil deleted the load-as-gems-in-initializer branch January 7, 2025 22:55
zzak added a commit to zzak/rails that referenced this pull request Jan 8, 2025
Fixes rails#54152

In rails#45100 we decided that when the variant_processor is :vips or
:mini_magick, we should try to eagerly load the library and throw a
warning if the library was not available.

However, because `:vips` is the default, this will always show the
warning unless the developer adds `image_processing` gem to their
dependencies.

If they do not want to do this, they can opt-out by setting
`config.active_storage.variant_processor = nil`.
@@ -1,22 +1,17 @@
# frozen_string_literal: true

begin
gem "mini_magick"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@skipkayhil how come you don't require the gem here? You do in the vips anlayzer, and I think that's causing issues, but I can't work if that's an intentional oversight.

Tanda @ Rails 8.1.0.alpha (test) :008 > gem "mini_magick"
true
Tanda @ Rails 8.1.0.alpha (test) :009 > MiniMagick
(web):9:in `<main>': uninitialized constant MiniMagick (NameError)

MiniMagick
^^^^^^^^^^
Did you mean?  MiniMime
Tanda @ Rails 8.1.0.alpha (test) :010 > ::MiniMagick
(web):10:in `<main>': uninitialized constant MiniMagick (NameError)

::MiniMagick
^^^^^^^^^^^^
Did you mean?  MiniMime
Tanda @ Rails 8.1.0.alpha (test) :011 > require "mini_magick"
true
Tanda @ Rails 8.1.0.alpha (test) :012 > MiniMagick
MiniMagick

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the missing require was not intentional

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants