Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f45f3d5
For Action Mailers use the mailers to get queue names
shashankmehra Mar 3, 2025
8d15a22
Queue name from mailer is the configured queue name and does not cont…
shashankmehra Mar 3, 2025
7aa89d7
Add support for Rails 7.1 in appraisal
shashankmehra Mar 3, 2025
bc4df8e
Add Rails 7.1 to CI matrix
shashankmehra Mar 3, 2025
477e14b
Reduce scope of custom Action Mailer handling to MailDeliveryJob only
shashankmehra Mar 4, 2025
880a504
Add test cases for different configurations for action mailer
shashankmehra Mar 4, 2025
86b3a06
Conditionally run mailer specific queue tests for Rails 7.1+ only
shashankmehra Mar 4, 2025
745557e
Clean up line added for debugging
shashankmehra Mar 4, 2025
e20992b
Add ruby 3.1 and 3.2 to test matrix
shashankmehra Mar 4, 2025
32eb33b
Set fail-fast to false temporarily
shashankmehra Mar 4, 2025
5ed7abe
Disable tests for Ruby 3.2 and Rails 6.x due to compatibility issues
shashankmehra Mar 4, 2025
f90a68d
Update CI matrix: drop EOL Ruby/Rails, add Ruby 3.3/3.4 and Rails 7.2
adis-io Apr 8, 2026
1190ce6
Exclude MailDeliveryJob subclasses from active_job_classes_with_match…
adis-io Apr 8, 2026
9138328
Bump minimum Ruby to 2.7 and add concurrent-ruby pin to gemfiles
adis-io Apr 8, 2026
c686dc0
Update CHANGELOG for unreleased changes
adis-io Apr 8, 2026
84017f1
Fix spec regexes for Ruby 3.4 compatibility
adis-io Apr 8, 2026
91c1750
Use .presence for queue_name_prefix in mailer_queue_name
adis-io Apr 8, 2026
8cb7b09
Do not run duplicated builds
adis-io Apr 8, 2026
f3adb71
Fix Rails 7.2 test app boot failure due to HealthController
adis-io Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Main

on: [push,pull_request]
on:
push:
branches: [main]
pull_request:

jobs:
build:
Expand All @@ -20,23 +23,52 @@ jobs:
strategy:
matrix:
ruby:
- '2.5'
- '2.6'
- '2.7'
- '3.0'
- '3.1'
- '3.2'
- '3.3'
- '3.4'
gemfile:
- gemfiles/activejob_6.0.x.gemfile
- gemfiles/activejob_6.1.x.gemfile
- gemfiles/activejob_7.0.x.gemfile
- gemfiles/activejob_7.1.x.gemfile
- gemfiles/activejob_7.2.x.gemfile
exclude:
- ruby: '2.5'
gemfile: gemfiles/activejob_7.0.x.gemfile
- ruby: '2.6'
# --- Rails 7.2 (Requires Ruby 3.1+) ---
# Exclude Ruby 2.7 to 3.0
- ruby: '2.7'
gemfile: gemfiles/activejob_7.2.x.gemfile
- ruby: '3.0'
gemfile: gemfiles/activejob_7.2.x.gemfile

# --- Rails 7.0 (Upper Bounds) ---
# Rails 7.0 does not officially support Ruby 3.4+
- ruby: '3.4'
gemfile: gemfiles/activejob_7.0.x.gemfile

# --- Rails 6.0 & 6.1 (Upper Bounds) ---
# Rails 6.0 and 6.1 do not officially support Ruby 3.1+ (many gems break)
- ruby: '3.1'
gemfile: gemfiles/activejob_6.0.x.gemfile
- ruby: '3.1'
gemfile: gemfiles/activejob_6.1.x.gemfile
- ruby: '3.2'
gemfile: gemfiles/activejob_6.0.x.gemfile
- ruby: '3.2'
gemfile: gemfiles/activejob_6.1.x.gemfile
- ruby: '3.3'
gemfile: gemfiles/activejob_6.0.x.gemfile
- ruby: '3.3'
gemfile: gemfiles/activejob_6.1.x.gemfile
- ruby: '3.4'
gemfile: gemfiles/activejob_6.0.x.gemfile
- ruby: '3.4'
gemfile: gemfiles/activejob_6.1.x.gemfile
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v5

- name: Install dependencies
env:
Expand Down
10 changes: 10 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,13 @@ appraise 'activejob-7.0.x' do
gem 'rails', '~> 7.0.0'
gem 'concurrent-ruby', '1.3.4'
end

appraise 'activejob-7.1.x' do
gem 'rails', '~> 7.1.0'
Comment thread
adis-io marked this conversation as resolved.
gem 'concurrent-ruby', '1.3.4'
end

appraise 'activejob-7.2.x' do
gem 'rails', '~> 7.2.0'
gem 'concurrent-ruby', '1.3.4'
end
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased](https://github.com/veeqo/advanced-sneakers-activejob/compare/v0.6.0...HEAD)

### Added
- [#42](https://github.com/veeqo/advanced-sneakers-activejob/pull/42) Add support for ActiveJob v7.1 and v7.2 (including ActionMailer queue consumer detection)
- [#42](https://github.com/veeqo/advanced-sneakers-activejob/pull/42) Add Ruby 3.3 and 3.4 to CI matrix

### Changed
- [#42](https://github.com/veeqo/advanced-sneakers-activejob/pull/42) Bump minimum Ruby version from 2.5 to 2.7

### Removed
- [#42](https://github.com/veeqo/advanced-sneakers-activejob/pull/42) Drop support for Ruby 2.5 and 2.6


## [0.6.0](https://github.com/veeqo/advanced-sneakers-activejob/compare/v0.5.0...v0.6.0) - 2022-02-15

Expand Down
2 changes: 1 addition & 1 deletion advanced-sneakers-activejob.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Gem::Specification.new do |spec|

spec.files = Dir['CHANGELOG.md', 'LICENSE.txt', 'README.md', 'lib/**/*']

spec.required_ruby_version = '>= 2.5'
spec.required_ruby_version = '>= 2.7'

spec.require_paths = ['lib']

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

source "https://rubygems.org"

gem "rails", "~> 4.2.11"
gem "rails", "~> 7.1.0"
Comment thread
adis-io marked this conversation as resolved.
gem "concurrent-ruby", "1.3.4"

gemspec path: "../"
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

source "https://rubygems.org"

gem "rails", "~> 5.2.4"
gem "rails", "~> 7.2.0"
gem "concurrent-ruby", "1.3.4"

gemspec path: "../"
30 changes: 28 additions & 2 deletions lib/advanced_sneakers_activejob/workers_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,41 @@ def define_active_job_consumers
active_job_classes_with_matching_adapter.each do |worker|
AdvancedSneakersActiveJob.define_consumer(queue_name: worker.new.queue_name)
end

action_mailer_classes_with_matching_adapter.each do |mailer|
AdvancedSneakersActiveJob.define_consumer(queue_name: mailer_queue_name(mailer))
end
end

private

def active_job_classes_with_matching_adapter
([ActiveJob::Base] + ActiveJob::Base.descendants).select do |klass|
klass.queue_adapter == ::ActiveJob::QueueAdapters::AdvancedSneakersAdapter ||
klass.queue_adapter.is_a?(::ActiveJob::QueueAdapters::AdvancedSneakersAdapter)
advanced_sneakers_adapter?(klass) &&
!(defined?(ActionMailer::Base) && klass <= ActionMailer::MailDeliveryJob)
end
end

def action_mailer_classes_with_matching_adapter
return [] if !defined?(ActionMailer::Base) ||
ActionMailer.gem_version < Gem::Version.new('6.0.0') ||
!advanced_sneakers_adapter?(ActionMailer::MailDeliveryJob)

([ActionMailer::Base] + ActionMailer::Base.descendants).select do |klass|
klass.delivery_job == ActionMailer::MailDeliveryJob
Comment thread
adis-io marked this conversation as resolved.
end
end

def advanced_sneakers_adapter?(klass)
klass.queue_adapter == ::ActiveJob::QueueAdapters::AdvancedSneakersAdapter ||
klass.queue_adapter.is_a?(::ActiveJob::QueueAdapters::AdvancedSneakersAdapter)
end

# Gets the queue name for the mailer with activejob prefix and delimiter
# Queue name from ActionMailer::Base.deliver_later_queue_name is not prefixed
# and has no delimiter, so we need to add them manually
def mailer_queue_name(mailer)
[ActiveJob::Base.queue_name_prefix.presence, mailer.deliver_later_queue_name.to_s].compact.join(ActiveJob::Base.queue_name_delimiter)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
subject { registry.foobar }

it 'raises NoMethodError' do
expect { subject }.to raise_error(NoMethodError, /undefined method `foobar'/)
expect { subject }.to raise_error(NoMethodError, /undefined method [`']foobar'/)
end
end
end
1 change: 1 addition & 0 deletions spec/apps/with_advanced_sneakers_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'bundler/setup'
require 'rails'
require 'active_job/railtie'
require 'action_controller/railtie'
require 'action_mailer/railtie' unless ENV['SKIP_MAILER']

$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
Expand Down
1 change: 1 addition & 0 deletions spec/apps/with_inline_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'bundler/setup'
require 'rails'
require 'active_job/railtie'
require 'action_controller/railtie'
require 'action_mailer/railtie' unless ENV['SKIP_MAILER']

$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
Expand Down
1 change: 1 addition & 0 deletions spec/apps/with_sneakers_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'bundler/setup'
require 'rails'
require 'active_job/railtie'
require 'action_controller/railtie'
require 'action_mailer/railtie' unless ENV['SKIP_MAILER']

require 'sneakers'
Expand Down
4 changes: 2 additions & 2 deletions spec/integration/action_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
in_app_process(adapter: :sneakers) { SampleMailer.greetings(name: 'Sneakers').deliver_later }

expect_logs name: 'rails',
to_include: /Enqueued ActionMailer::(Mail)?DeliveryJob to Sneakers\(mailers\) with arguments: "SampleMailer", "greetings", "deliver_now", .*\{:name=>"Sneakers"\}/,
to_include: /Enqueued ActionMailer::(Mail)?DeliveryJob to Sneakers\(mailers\) with arguments: "SampleMailer", "greetings", "deliver_now", .*\{(?::name=>|name: )"Sneakers"\}/,
to_exclude: [
'Hello, Sneakers',
/Performed ActionMailer::(Mail)?DeliveryJob/
Expand All @@ -25,7 +25,7 @@

expect_logs name: 'rails',
to_include: [
/Enqueued ActionMailer::(Mail)?DeliveryJob to AdvancedSneakers\(mailers\) with arguments: "SampleMailer", "greetings", "deliver_now", .*\{:name=>"Advanced sneakers"\}/,
/Enqueued ActionMailer::(Mail)?DeliveryJob to AdvancedSneakers\(mailers\) with arguments: "SampleMailer", "greetings", "deliver_now", .*\{(?::name=>|name: )"Advanced sneakers"\}/,
'Hello, Advanced sneakers',
/Performed ActionMailer::(Mail)?DeliveryJob/
]
Expand Down
112 changes: 101 additions & 11 deletions spec/integration/consumers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,90 @@ class DynamicQueueJob < ApplicationJob
end
end

if ActiveJob.gem_version >= Gem::Version.new('5.0')
context 'when there are ActiveJob classes with custom queue adapter' do
context 'when there are ActiveJob classes with custom queue adapter' do
subject do
in_app_process(adapter: :advanced_sneakers) do
class FooJob < ApplicationJob
self.queue_adapter = :async

queue_as :bar
end

AdvancedSneakersActiveJob.configure { |c| c.activejob_workers_strategy = :only }

Sneakers::Worker::Classes.call.map { |consumer| [consumer.name, consumer.queue_name] }.to_h
end
end

it 'are defined for queue from matching adapter only' do
expected_consumers = {
'AdvancedSneakersActiveJob::DefaultConsumer' => 'default', # default consumer
'AdvancedSneakersActiveJob::MailersConsumer' => 'mailers', # action mailer consumer
'AdvancedSneakersActiveJob::CustomConsumer' => 'custom' # see CustomQueueJob in spec/apps/app/jobs
}

expect(subject.first).to eq(expected_consumers)
end
end

context 'when advanced_sneakers is set as custom adapter' do
subject do
in_app_process(adapter: :inline) do
class FooJob < ApplicationJob
self.queue_adapter = :advanced_sneakers

queue_as :bar
end

AdvancedSneakersActiveJob.configure { |c| c.activejob_workers_strategy = :only }

Sneakers::Worker::Classes.call.map { |consumer| [consumer.name, consumer.queue_name] }.to_h
end
end

it 'are defined for queue from matching adapter only' do
expected_consumers = {
'AdvancedSneakersActiveJob::BarConsumer' => 'bar' # bar queue consumer for FooJob
}

expect(subject.first).to eq(expected_consumers)
end
end

context 'when ActionMailer::Base has deliver_later_queue_name globally defined' do
subject do
in_app_process(adapter: :advanced_sneakers) do
ActionMailer::Base.deliver_later_queue_name = 'bar'

AdvancedSneakersActiveJob.configure { |c| c.activejob_workers_strategy = :only }

Sneakers::Worker::Classes.call.map { |consumer| [consumer.name, consumer.queue_name] }.to_h
end
end

it 'are defined for queue from matching adapter only' do
expected_consumers = {
'AdvancedSneakersActiveJob::BarConsumer' => 'bar', # bar queue consumer for FooMailer
'AdvancedSneakersActiveJob::DefaultConsumer' => 'default', # default consumer
'AdvancedSneakersActiveJob::CustomConsumer' => 'custom', # see CustomQueueJob in spec/apps/app/jobs
}

expect(subject.first).to eq(expected_consumers)
end
end

# Support for mailer specific queue name was added in Rails 7.1
# https://github.com/rails/rails/pull/47408
if ActiveJob.gem_version >= Gem::Version.new('7.1')
context 'when there are ActionMailer classes with queue defined' do
subject do
in_app_process(adapter: :advanced_sneakers) do
class FooJob < ApplicationJob
self.queue_adapter = :async
class FooMailer < ActionMailer::Base
self.deliver_later_queue_name = 'bar'
end

queue_as :bar
class BarMailer < ActionMailer::Base
self.deliver_later_queue_name = 'baz'
end

AdvancedSneakersActiveJob.configure { |c| c.activejob_workers_strategy = :only }
Expand All @@ -96,24 +172,35 @@ class FooJob < ApplicationJob

it 'are defined for queue from matching adapter only' do
expected_consumers = {
'AdvancedSneakersActiveJob::BarConsumer' => 'bar', # bar queue consumer for FooMailer
'AdvancedSneakersActiveJob::BazConsumer' => 'baz', # baz queue consumer for BarMailer
'AdvancedSneakersActiveJob::DefaultConsumer' => 'default', # default consumer
'AdvancedSneakersActiveJob::MailersConsumer' => 'mailers', # action mailer consumer
'AdvancedSneakersActiveJob::CustomConsumer' => 'custom' # see CustomQueueJob in spec/apps/app/jobs
'AdvancedSneakersActiveJob::CustomConsumer' => 'custom', # see CustomQueueJob in spec/apps/app/jobs
}

expect(subject.first).to eq(expected_consumers)
end
end

context 'when advanced_sneakers is set as custom adapter' do
context 'when there are ActionMailer classes with custom delivery jobs' do
subject do
in_app_process(adapter: :inline) do
class FooJob < ApplicationJob
self.queue_adapter = :advanced_sneakers
in_app_process(adapter: :advanced_sneakers) do
class CustomDeliveryJob < ActionMailer::MailDeliveryJob
self.queue_adapter = :async

queue_as :bar
end

class FooMailer < ActionMailer::Base
self.delivery_job = CustomDeliveryJob
self.deliver_later_queue_name = 'bar'
end

class BarMailer < ActionMailer::Base
self.deliver_later_queue_name = 'baz'
end

AdvancedSneakersActiveJob.configure { |c| c.activejob_workers_strategy = :only }

Sneakers::Worker::Classes.call.map { |consumer| [consumer.name, consumer.queue_name] }.to_h
Expand All @@ -122,7 +209,10 @@ class FooJob < ApplicationJob

it 'are defined for queue from matching adapter only' do
expected_consumers = {
'AdvancedSneakersActiveJob::BarConsumer' => 'bar' # bar queue consumer for FooJob
'AdvancedSneakersActiveJob::BazConsumer' => 'baz', # baz queue consumer for BarMailer
'AdvancedSneakersActiveJob::DefaultConsumer' => 'default', # default consumer
'AdvancedSneakersActiveJob::MailersConsumer' => 'mailers', # action mailer consumer
'AdvancedSneakersActiveJob::CustomConsumer' => 'custom', # see CustomQueueJob in spec/apps/app/jobs
}

expect(subject.first).to eq(expected_consumers)
Expand Down