Skip to content

Commit 497e1fb

Browse files
jherdmanrosa
authored andcommitted
Error when recurring tasks are invalid
Resolves #414
1 parent 012e4f8 commit 497e1fb

File tree

8 files changed

+79
-7
lines changed

8 files changed

+79
-7
lines changed

lib/solid_queue/configuration.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ def configured_processes
3636
end
3737
end
3838

39+
def valid?
40+
skip_recurring_tasks? || recurring_tasks.none? || recurring_tasks.all?(&:valid?)
41+
end
42+
43+
def invalid_tasks
44+
recurring_tasks.select(&:invalid?)
45+
end
46+
3947
def max_number_of_threads
4048
# At most "threads" in each worker + 1 thread for the worker + 1 thread for the heartbeat task
4149
workers_options.map { |options| options[:threads] }.max + 2
@@ -100,7 +108,7 @@ def dispatchers_options
100108
def recurring_tasks
101109
@recurring_tasks ||= recurring_tasks_config.map do |id, options|
102110
RecurringTask.from_configuration(id, **options)
103-
end.select(&:valid?)
111+
end
104112
end
105113

106114
def processes_config

lib/solid_queue/supervisor.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,27 @@ def start(**options)
1111
configuration = Configuration.new(**options)
1212

1313
if configuration.configured_processes.any?
14-
new(configuration).tap(&:start)
14+
if configuration.valid?
15+
new(configuration).tap(&:start)
16+
else
17+
abort_due_to_invalid_tasks(configuration)
18+
end
1519
else
1620
abort "No workers or processed configured. Exiting..."
1721
end
1822
end
23+
24+
private
25+
def abort_due_to_invalid_tasks(configuration)
26+
error_messages = configuration.invalid_tasks
27+
.map do |task|
28+
all_messages = task.errors.full_messages.map { |msg| "\t#{msg}" }.join("\n")
29+
"#{task.key}:\n#{all_messages}"
30+
end
31+
.join("\n")
32+
33+
abort "Invalid processes configured:\n#{error_messages}"
34+
end
1935
end
2036

2137
def initialize(configuration)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
periodic_store_result:
2+
class: StoreResultJorrrrrrb
3+
queue: default
4+
args: [42, { status: "custom_status" }]
5+
schedule: every second

test/test_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ExpectedTestError < RuntimeError; end
2828

2929

3030
class ActiveSupport::TestCase
31-
include ProcessesTestHelper, JobsTestHelper
31+
include ConfigurationTestHelper, ProcessesTestHelper, JobsTestHelper
3232

3333
setup do
3434
# Could be cleaner with one several minitest gems, but didn't want to add new dependency
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module ConfigurationTestHelper
4+
def config_file_path(name)
5+
Rails.root.join("config/#{name}.yml")
6+
end
7+
end

test/test_helpers/processes_test_helper.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ def run_supervisor_as_fork(**options)
77
end
88
end
99

10+
def run_supervisor_as_fork_with_captured_io(**options)
11+
pid = nil
12+
out, err = capture_subprocess_io do
13+
pid = run_supervisor_as_fork(**options)
14+
wait_for_registered_processes(4)
15+
end
16+
17+
[ pid, out, err ]
18+
end
19+
1020
def wait_for_registered_processes(count, timeout: 1.second)
1121
wait_while_with_timeout(timeout) { SolidQueue::Process.count != count }
1222
end

test/unit/configuration_test.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,26 @@ class ConfigurationTest < ActiveSupport::TestCase
9090
assert_processes configuration, :dispatcher, 1, polling_interval: 0.1, recurring_tasks: nil
9191
end
9292

93+
test "detects when there are invalid recurring tasks" do
94+
configuration = SolidQueue::Configuration.new(recurring_schedule_file: config_file_path(:recurring_with_invalid))
95+
96+
assert_not configuration.valid?
97+
98+
assert_equal configuration.invalid_tasks.size, 1
99+
end
100+
101+
test "is valid when there are no recurring tasks" do
102+
configuration = SolidQueue::Configuration.new(recurring_schedule_file: config_file_path(:empty_recurring))
103+
104+
assert configuration.valid?
105+
end
106+
107+
test "is valid when recurring tasks are skipped" do
108+
configuration = SolidQueue::Configuration.new(skip_recurring: true)
109+
110+
assert configuration.valid?
111+
end
112+
93113
private
94114
def assert_processes(configuration, kind, count, **attributes)
95115
processes = configuration.configured_processes.select { |p| p.kind == kind }
@@ -121,8 +141,4 @@ def assert_equal_value(expected_value, value)
121141
assert_equal expected_value, value
122142
end
123143
end
124-
125-
def config_file_path(name)
126-
Rails.root.join("config/#{name}.yml")
127-
end
128144
end

test/unit/supervisor_test.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ class SupervisorTest < ActiveSupport::TestCase
4848
assert_not process_exists?(pid)
4949
end
5050

51+
test "start with invalid configuration" do
52+
pid, _out, err = run_supervisor_as_fork_with_captured_io(recurring_schedule_file: config_file_path(:recurring_with_invalid), skip_recurring: false)
53+
54+
sleep(0.5)
55+
assert_no_registered_processes
56+
57+
assert_not process_exists?(pid)
58+
assert_match %r{Invalid processes configured}, err
59+
end
60+
5161
test "create and delete pidfile" do
5262
assert_not File.exist?(@pidfile)
5363

0 commit comments

Comments
 (0)