diff options
22 files changed, 109 insertions, 34 deletions
diff --git a/Gemfile.lock b/Gemfile.lock index 7b30653745..b07fc7b0ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -317,7 +317,7 @@ GEM mimemagic (0.3.3) mini_magick (4.9.2) mini_mime (1.0.1) - mini_portile2 (2.3.0) + mini_portile2 (2.4.0) minitest (5.11.3) minitest-bisect (1.4.0) minitest-server (~> 1.0) @@ -340,13 +340,13 @@ GEM mysql2 (0.5.2-x86-mingw32) nio4r (2.3.1) nio4r (2.3.1-java) - nokogiri (1.8.5) - mini_portile2 (~> 2.3.0) - nokogiri (1.8.5-java) - nokogiri (1.8.5-x64-mingw32) - mini_portile2 (~> 2.3.0) - nokogiri (1.8.5-x86-mingw32) - mini_portile2 (~> 2.3.0) + nokogiri (1.9.1) + mini_portile2 (~> 2.4.0) + nokogiri (1.9.1-java) + nokogiri (1.9.1-x64-mingw32) + mini_portile2 (~> 2.4.0) + nokogiri (1.9.1-x86-mingw32) + mini_portile2 (~> 2.4.0) os (1.0.0) parallel (1.12.1) parser (2.5.3.0) diff --git a/actionmailbox/app/controllers/action_mailbox/base_controller.rb b/actionmailbox/app/controllers/action_mailbox/base_controller.rb index cc22ea803c..f0f1f555e6 100644 --- a/actionmailbox/app/controllers/action_mailbox/base_controller.rb +++ b/actionmailbox/app/controllers/action_mailbox/base_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ActionMailbox - # The base class for all Active Mailbox ingress controllers. + # The base class for all Action Mailbox ingress controllers. class BaseController < ActionController::Base skip_forgery_protection diff --git a/actionmailbox/app/controllers/action_mailbox/ingresses/postfix/inbound_emails_controller.rb b/actionmailbox/app/controllers/action_mailbox/ingresses/postfix/inbound_emails_controller.rb index 1871893e99..c0d5002a12 100644 --- a/actionmailbox/app/controllers/action_mailbox/ingresses/postfix/inbound_emails_controller.rb +++ b/actionmailbox/app/controllers/action_mailbox/ingresses/postfix/inbound_emails_controller.rb @@ -35,7 +35,7 @@ module ActionMailbox # # Alternatively, provide the password in the +RAILS_INBOUND_EMAIL_PASSWORD+ environment variable. # - # 3. {Configure Postfix}{https://serverfault.com/questions/258469/how-to-configure-postfix-to-pipe-all-incoming-email-to-a-script} + # 3. {Configure Postfix}[https://serverfault.com/questions/258469/how-to-configure-postfix-to-pipe-all-incoming-email-to-a-script] # to pipe inbound emails to <tt>bin/rails action_mailbox:ingress:postfix</tt>, providing the +URL+ of the Postfix # ingress and the +INGRESS_PASSWORD+ you previously generated. # diff --git a/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb b/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb index ec4111fefa..58da33d85e 100644 --- a/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb +++ b/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb @@ -35,7 +35,7 @@ module ActionMailbox # # Alternatively, provide the password in the +RAILS_INBOUND_EMAIL_PASSWORD+ environment variable. # - # 3. {Configure SendGrid Inbound Parse}{https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/} + # 3. {Configure SendGrid Inbound Parse}[https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/] # to forward inbound emails to +/rails/action_mailbox/sendgrid/inbound_emails+ with the username +actionmailbox+ and # the password you previously generated. If your application lived at <tt>https://example.com</tt>, you would # configure SendGrid with the following fully-qualified URL: diff --git a/actionmailbox/lib/action_mailbox/base.rb b/actionmailbox/lib/action_mailbox/base.rb index 76c3a4886c..4ac594b9f8 100644 --- a/actionmailbox/lib/action_mailbox/base.rb +++ b/actionmailbox/lib/action_mailbox/base.rb @@ -77,7 +77,7 @@ module ActionMailbox @inbound_email = inbound_email end - def perform_processing + def perform_processing #:nodoc: track_status_of_inbound_email do run_callbacks :process do process @@ -92,11 +92,12 @@ module ActionMailbox # Overwrite in subclasses end - def finished_processing? + def finished_processing? #:nodoc: inbound_email.delivered? || inbound_email.bounced? end + # Enqueues the given +message+ for delivery and changes the inbound email's status to +:bounced+. def bounce_with(message) inbound_email.bounced! message.deliver_later @@ -113,3 +114,5 @@ module ActionMailbox end end end + +ActiveSupport.run_load_hooks :action_mailbox, ActionMailbox::Base diff --git a/actionmailbox/lib/action_mailbox/test_case.rb b/actionmailbox/lib/action_mailbox/test_case.rb index a501e8a7ca..5e78e428d3 100644 --- a/actionmailbox/lib/action_mailbox/test_case.rb +++ b/actionmailbox/lib/action_mailbox/test_case.rb @@ -8,3 +8,5 @@ module ActionMailbox include ActionMailbox::TestHelper end end + +ActiveSupport.run_load_hooks :action_mailbox_test_case, ActionMailbox::TestCase diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 1243236c09..346d4b067a 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -146,7 +146,7 @@ module ActiveRecord replica? || prevent_writes end - # Prevent writing to the database regardless of role. + # Prevent writing to the database regardless of role. # # In some cases you may want to prevent writes to the database # even if you are on a database that can write. `while_preventing_writes` diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index dbc6614b93..10961ed9c8 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -97,19 +97,11 @@ module ActiveRecord end def supports_datetime_with_precision? - if mariadb? - version >= "5.3.0" - else - version >= "5.6.4" - end + mariadb? || version >= "5.6.4" end def supports_virtual_columns? - if mariadb? - version >= "5.2.0" - else - version >= "5.7.5" - end + mariadb? || version >= "5.7.5" end def supports_advisory_locks? diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 8f4d292a4b..fc564d59e2 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -350,9 +350,7 @@ module ActiveRecord # Initialize an empty model object from +attributes+. # +attributes+ should be an attributes object, and unlike the # `initialize` method, no assignment calls are made per attribute. - # - # :nodoc: - def init_with_attributes(attributes, new_record = false) + def init_with_attributes(attributes, new_record = false) # :nodoc: init_internals @new_record = new_record diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 0fa5ba2e50..3ef6e7928f 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -245,7 +245,7 @@ module ActiveRecord if distinct && (group_values.any? || select_values.empty? && order_values.empty?) column_name = primary_key end - elsif /\s*DISTINCT[\s(]+/i.match?(column_name.to_s) + elsif column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name) distinct = nil end end diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 66e594d771..05d8aa59c4 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -163,6 +163,16 @@ module ActiveRecord end end + def test_preventing_writes_predicate + assert_not_predicate @connection, :preventing_writes? + + @connection.while_preventing_writes do + assert_predicate @connection, :preventing_writes? + end + + assert_not_predicate @connection, :preventing_writes? + end + def test_errors_when_an_insert_query_is_called_while_preventing_writes assert_no_queries do assert_raises(ActiveRecord::ReadOnlyError) do diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 4d3db912c5..5b5202d167 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -432,6 +432,8 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_count_selected_field_with_include assert_equal 6, Account.includes(:firm).distinct.count assert_equal 4, Account.includes(:firm).distinct.select(:credit_limit).count + assert_equal 4, Account.includes(:firm).distinct.count("DISTINCT credit_limit") + assert_equal 4, Account.includes(:firm).distinct.count("DISTINCT(credit_limit)") end def test_should_not_perform_joined_include_by_default diff --git a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb index 0b3fb82e12..865aacc1b5 100644 --- a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb @@ -108,6 +108,7 @@ module ActiveRecord ActiveRecord::Base.connected_to(role: :reading) do @ro_handler = ActiveRecord::Base.connection_handler assert_equal ActiveRecord::Base.connection_handler, ActiveRecord::Base.connection_handlers[:reading] + assert_equal :reading, ActiveRecord::Base.current_role assert ActiveRecord::Base.connected_to?(role: :reading) assert_not ActiveRecord::Base.connected_to?(role: :writing) end @@ -115,6 +116,7 @@ module ActiveRecord ActiveRecord::Base.connected_to(role: :writing) do assert_equal ActiveRecord::Base.connection_handler, ActiveRecord::Base.connection_handlers[:writing] assert_not_equal @ro_handler, ActiveRecord::Base.connection_handler + assert_equal :writing, ActiveRecord::Base.current_role assert ActiveRecord::Base.connected_to?(role: :writing) assert_not ActiveRecord::Base.connected_to?(role: :reading) end @@ -129,6 +131,7 @@ module ActiveRecord previous_url, ENV["DATABASE_URL"] = ENV["DATABASE_URL"], "postgres://localhost/foo" ActiveRecord::Base.connected_to(database: { writing: "postgres://localhost/bar" }) do + assert_equal :writing, ActiveRecord::Base.current_role assert ActiveRecord::Base.connected_to?(role: :writing) handler = ActiveRecord::Base.connection_handler @@ -148,6 +151,7 @@ module ActiveRecord config = { adapter: "sqlite3", database: "db/readonly.sqlite3" } ActiveRecord::Base.connected_to(database: { writing: config }) do + assert_equal :writing, ActiveRecord::Base.current_role assert ActiveRecord::Base.connected_to?(role: :writing) handler = ActiveRecord::Base.connection_handler @@ -187,6 +191,7 @@ module ActiveRecord @prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config ActiveRecord::Base.connected_to(database: :readonly) do + assert_equal :readonly, ActiveRecord::Base.current_role assert ActiveRecord::Base.connected_to?(role: :readonly) handler = ActiveRecord::Base.connection_handler @@ -211,6 +216,7 @@ module ActiveRecord assert_equal 1, ActiveRecord::Base.connection_handlers.size assert_equal ActiveRecord::Base.connection_handler, ActiveRecord::Base.connection_handlers[:writing] + assert_equal :writing, ActiveRecord::Base.current_role assert ActiveRecord::Base.connected_to?(role: :writing) ensure ActiveRecord::Base.configurations = @prev_configs diff --git a/activestorage/CHANGELOG.md b/activestorage/CHANGELOG.md index cece15ff06..fbc78a50ab 100644 --- a/activestorage/CHANGELOG.md +++ b/activestorage/CHANGELOG.md @@ -1,3 +1,14 @@ +* Replace `config.active_storage.queue` with two options that indicate which + queues analysis and purge jobs should use, respectively: + + * `config.active_storage.queues.analysis` + * `config.active_storage.queues.purge` + + `config.active_storage.queue` is preferred over the new options when it's + set, but it is deprecated and will be removed in Rails 6.1. + + *George Claghorn* + * Permit generating variants of TIFF images. *Luciano Sousa* diff --git a/activestorage/app/jobs/active_storage/analyze_job.rb b/activestorage/app/jobs/active_storage/analyze_job.rb index 804ee4557a..35d043d508 100644 --- a/activestorage/app/jobs/active_storage/analyze_job.rb +++ b/activestorage/app/jobs/active_storage/analyze_job.rb @@ -2,6 +2,8 @@ # Provides asynchronous analysis of ActiveStorage::Blob records via ActiveStorage::Blob#analyze_later. class ActiveStorage::AnalyzeJob < ActiveStorage::BaseJob + queue_as { ActiveStorage.queues[:analysis] } + retry_on ActiveStorage::IntegrityError, attempts: 10, wait: :exponentially_longer def perform(blob) diff --git a/activestorage/app/jobs/active_storage/base_job.rb b/activestorage/app/jobs/active_storage/base_job.rb index 6caab42a2d..7bc2064dc5 100644 --- a/activestorage/app/jobs/active_storage/base_job.rb +++ b/activestorage/app/jobs/active_storage/base_job.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true class ActiveStorage::BaseJob < ActiveJob::Base - queue_as { ActiveStorage.queue } end diff --git a/activestorage/app/jobs/active_storage/purge_job.rb b/activestorage/app/jobs/active_storage/purge_job.rb index 2604977bf1..5ceb222005 100644 --- a/activestorage/app/jobs/active_storage/purge_job.rb +++ b/activestorage/app/jobs/active_storage/purge_job.rb @@ -2,6 +2,8 @@ # Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later. class ActiveStorage::PurgeJob < ActiveStorage::BaseJob + queue_as { ActiveStorage.queues[:purge] } + discard_on ActiveRecord::RecordNotFound retry_on ActiveRecord::Deadlocked, attempts: 10, wait: :exponentially_longer diff --git a/activestorage/lib/active_storage.rb b/activestorage/lib/active_storage.rb index e127b4cd49..e542c4b2ca 100644 --- a/activestorage/lib/active_storage.rb +++ b/activestorage/lib/active_storage.rb @@ -42,7 +42,7 @@ module ActiveStorage mattr_accessor :logger mattr_accessor :verifier - mattr_accessor :queue + mattr_accessor :queues, default: {} mattr_accessor :previewers, default: [] mattr_accessor :analyzers, default: [] mattr_accessor :variant_processor, default: :mini_magick diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb index e2e9b70b69..384e6ebfa6 100644 --- a/activestorage/lib/active_storage/engine.rb +++ b/activestorage/lib/active_storage/engine.rb @@ -20,6 +20,7 @@ module ActiveStorage config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ] config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer, ActiveStorage::Analyzer::VideoAnalyzer ] config.active_storage.paths = ActiveSupport::OrderedOptions.new + config.active_storage.queues = ActiveSupport::OrderedOptions.new config.active_storage.variable_content_types = %w( image/png @@ -61,7 +62,6 @@ module ActiveStorage initializer "active_storage.configs" do config.after_initialize do |app| ActiveStorage.logger = app.config.active_storage.logger || Rails.logger - ActiveStorage.queue = app.config.active_storage.queue ActiveStorage.variant_processor = app.config.active_storage.variant_processor || :mini_magick ActiveStorage.previewers = app.config.active_storage.previewers || [] ActiveStorage.analyzers = app.config.active_storage.analyzers || [] @@ -117,6 +117,20 @@ module ActiveStorage end end + initializer "active_storage.queues" do + config.after_initialize do |app| + if queue = app.config.active_storage.queue + ActiveSupport::Deprecation.warn \ + "config.active_storage.queue is deprecated and will be removed in Rails 6.1. " \ + "Set config.active_storage.queues.purge and config.active_storage.queues.analysis instead." + + ActiveStorage.queues = { purge: queue, analysis: queue } + else + ActiveStorage.queues = app.config.active_storage.queues || {} + end + end + end + initializer "active_storage.reflection" do ActiveSupport.on_load(:active_record) do include Reflection::ActiveRecordExtensions diff --git a/guides/source/action_mailbox_basics.md b/guides/source/action_mailbox_basics.md index 87000bf5cf..eb8a14b4d2 100644 --- a/guides/source/action_mailbox_basics.md +++ b/guides/source/action_mailbox_basics.md @@ -50,7 +50,7 @@ Install the [`aws-sdk-sns`](https://rubygems.org/gems/aws-sdk-sns) gem: ```ruby # Gemfile gem "aws-sdk-sns", ">= 1.9.0", require: false - ``` +``` Tell Action Mailbox to accept emails from SES: diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 7193278581..3b21197ae4 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -619,6 +619,29 @@ Defaults to `'signed cookie'`. development mode, but for large test suites, disabling this option in the test environment can improve performance. This defaults to `true`. + +### Configuring Action Mailbox + +`config.action_mailbox` provides the following configuration options: + +* `config.action_mailbox.logger` contains the logger used by Action Mailbox. It accepts a logger conforming to the interface of Log4r or the default Ruby Logger class. The default is `Rails.logger`. + + ```ruby + config.action_mailbox.logger = ActiveSupport::Logger.new(STDOUT) + ``` + +* `config.action_mailbox.incinerate_after` accepts an `ActiveSupport::Duration` indicating how long after processing `ActionMailbox::InboundEmail` records should be destroyed. It defaults to `30.days`. + + ```ruby + # Incinerate inbound emails 14 days after processing. + config.action_mailbox.incinerate_after = 14.days + ``` + +* `config.action_mailbox.queues.incineration` accepts a symbol indicating the Active Job queue to use for incineration jobs. It defaults to `:action_mailbox_incineration`. + +* `config.action_mailbox.queues.routing` accepts a symbol indicating the Active Job queue to use for routing jobs. It defaults to `:action_mailbox_routing`. + + ### Configuring Action Mailer There are a number of settings available on `config.action_mailer`: @@ -820,10 +843,16 @@ normal Rails server. * `config.active_storage.content_types_to_serve_as_binary` accepts an array of strings indicating the content types that Active Storage will always serve as an attachment, rather than inline. The default is `%w(text/html text/javascript image/svg+xml application/postscript application/x-shockwave-flash text/xml application/xml application/xhtml+xml)`. -* `config.active_storage.queue` can be used to set the name of the Active Job queue used to perform jobs like analyzing the content of a blob or purging a blog. +* `config.active_storage.queues.analysis` accepts a symbol indicating the Active Job queue to use for analysis jobs. When this option is `nil`, analysis jobs are sent to the default Active Job queue (see `config.active_job.default_queue_name`). + + ```ruby + config.active_storage.queues.analysis = :low_priority + ``` + +* `config.active_storage.queues.purge` accepts a symbol indicating the Active Job queue to use for purge jobs. When this option is `nil`, purge jobs are sent to the default Active Job queue (see `config.active_job.default_queue_name`). ```ruby - config.active_storage.queue = :low_priority + config.active_storage.queues.purge = :low_priority ``` * `config.active_storage.logger` can be used to set the logger used by Active Storage. Accepts a logger conforming to the interface of Log4r or the default Ruby Logger class. @@ -847,6 +876,7 @@ text/javascript image/svg+xml application/postscript application/x-shockwave-fla The default is `/rails/active_storage` + ### Configuring a Database Just about every Rails application will interact with a database. You can connect to the database by setting an environment variable `ENV['DATABASE_URL']` or by using a configuration file called `config/database.yml`. diff --git a/guides/source/engines.md b/guides/source/engines.md index 1e93a19c84..bd0542ffc1 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -1505,6 +1505,9 @@ To hook into the initialization process of one of the following classes use the | `ActionController::TestCase` | `action_controller_test_case` | | `ActionDispatch::IntegrationTest` | `action_dispatch_integration_test` | | `ActionDispatch::SystemTestCase` | `action_dispatch_system_test_case` | +| `ActionMailbox::Base` | `action_mailbox` | +| `ActionMailbox::InboundEmail` | `action_mailbox_inbound_email` | +| `ActionMailbox::TestCase` | `action_mailbox_test_case` | | `ActionMailer::Base` | `action_mailer` | | `ActionMailer::TestCase` | `action_mailer_test_case` | | `ActionView::Base` | `action_view` | @@ -1512,6 +1515,7 @@ To hook into the initialization process of one of the following classes use the | `ActiveJob::Base` | `active_job` | | `ActiveJob::TestCase` | `active_job_test_case` | | `ActiveRecord::Base` | `active_record` | +| `ActiveStorage::Blob` | `active_storage_blob` | | `ActiveSupport::TestCase` | `active_support_test_case` | | `i18n` | `i18n` | |