Skip to content

feat: allow using a pattern of file to specify multiple configurations of recurring tasks #620

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ Solid Queue supports defining recurring tasks that run at specific times in the
bin/jobs --recurring_schedule_file=config/schedule.yml
```

It's also possible to define recurring tasks in several configuration files, for that specify a pattern of recurring tasks via `SolidQueue.recurring_config_file_pattern`.

You can completely disable recurring tasks by setting the environment variable `SOLID_QUEUE_SKIP_RECURRING=true` or by using the `--skip-recurring` option with `bin/jobs`.

The configuration itself looks like this:
Expand Down
2 changes: 2 additions & 0 deletions lib/solid_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ module SolidQueue
mattr_accessor :clear_finished_jobs_after, default: 1.day
mattr_accessor :default_concurrency_control_period, default: 3.minutes

mattr_accessor :recurring_config_file_pattern, default: SolidQueue::Configuration::DEFAULT_RECURRING_SCHEDULE_FILE_PATH

delegate :on_start, :on_stop, :on_exit, to: Supervisor

[ Dispatcher, Scheduler, Worker ].each do |process|
Expand Down
10 changes: 9 additions & 1 deletion lib/solid_queue/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,15 @@ def processes_config

def recurring_tasks_config
@recurring_tasks_config ||= begin
config_from options[:recurring_schedule_file]
if options.key?(:recurring_schedule_config_pattern)
matching_configurations = Dir.glob(Rails.root.join(options[:recurring_schedule_config_pattern]))
matching_configurations
.each_with_object({}) do |config_file, recurring_configuration|
recurring_configuration.merge!(config_from config_file)
end
else
config_from options[:recurring_schedule_file]
end
end
end

Expand Down
5 changes: 5 additions & 0 deletions test/dummy/config/recurring_matching_pattern_a.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
periodic_store_result_a:
class: StoreResultJob
queue: default
args: [ 42, { status: "custom_status" } ]
schedule: every second
5 changes: 5 additions & 0 deletions test/dummy/config/recurring_matching_pattern_b.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
periodic_store_result_b:
class: StoreResultJob
queue: default
args: [ 42, { status: "custom_status" } ]
schedule: every second
17 changes: 16 additions & 1 deletion test/unit/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class ConfigurationTest < ActiveSupport::TestCase
assert_processes configuration, :scheduler, 1

scheduler = configuration.configured_processes.second.instantiate
assert_equal 1, scheduler.recurring_schedule.configured_tasks.count
assert_has_recurring_task scheduler, key: "periodic_store_result", class_name: "StoreResultJob", schedule: "every second"
end

Expand All @@ -77,6 +78,7 @@ class ConfigurationTest < ActiveSupport::TestCase
assert_processes configuration, :scheduler, 1

scheduler = configuration.configured_processes.first.instantiate
assert_equal 1, scheduler.recurring_schedule.configured_tasks.count
assert_has_recurring_task scheduler, key: "periodic_store_result", class_name: "StoreResultJob", schedule: "every second"
end

Expand Down Expand Up @@ -143,6 +145,20 @@ class ConfigurationTest < ActiveSupport::TestCase
configuration.errors.full_messages.first
end

test "multiple recurring configuration files" do
configuration = SolidQueue::Configuration.new(recurring_schedule_config_pattern: "config/recurring_matching_pattern_*.yml")

assert configuration.valid?
assert_processes configuration, :scheduler, 1

scheduler = configuration.configured_processes.find { |process| process.kind == :scheduler }.instantiate

assert_equal 2, scheduler.recurring_schedule.configured_tasks.count
assert_has_recurring_task scheduler, key: "periodic_store_result_a", class_name: "StoreResultJob", schedule: "every second"
assert_has_recurring_task scheduler, key: "periodic_store_result_b", class_name: "StoreResultJob", schedule: "every second"
ensure
end

private
def assert_processes(configuration, kind, count, **attributes)
processes = configuration.configured_processes.select { |p| p.kind == kind }
Expand All @@ -159,7 +175,6 @@ def assert_processes(configuration, kind, count, **attributes)
end

def assert_has_recurring_task(scheduler, key:, **attributes)
assert_equal 1, scheduler.recurring_schedule.configured_tasks.count
task = scheduler.recurring_schedule.configured_tasks.detect { |t| t.key == key }

attributes.each do |attr, value|
Expand Down
Loading