Skip to content

Commit 62bfa37

Browse files
committed
Update tests and README
1 parent 29778e7 commit 62bfa37

File tree

4 files changed

+57
-36
lines changed

4 files changed

+57
-36
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ scheduler:
282282

283283
This controls how frequently the scheduler wakes up to enqueue due recurring jobs and reload dynamic tasks.
284284

285+
> **Note:** The scheduler process always starts by default to support dynamic recurring tasks, even if no static tasks are configured in `config/recurring.yml`. If you don't use recurring tasks at all, you can disable the scheduler by setting `SOLID_QUEUE_SKIP_RECURRING=true` or passing `skip_recurring: true` in the configuration.
286+
285287
### Queue order and priorities
286288

287289
As mentioned above, if you specify a list of queues for a worker, these will be polled in the order given, such as for the list `real_time,background`, no jobs will be taken from `background` unless there aren't any more jobs waiting in `real_time`.

lib/solid_queue/configuration.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ def dispatchers
143143
def schedulers
144144
return [] if skip_recurring_tasks?
145145

146+
# Always start a scheduler (even with no static recurring tasks) to support
147+
# dynamic tasks that may be added at runtime via SolidQueue.schedule_task.
148+
# Use skip_recurring: true or SOLID_QUEUE_SKIP_RECURRING=true to disable.
146149
[ Process.new(:scheduler, { recurring_tasks:, **scheduler_options.with_defaults(SCHEDULER_DEFAULTS) }) ]
147150
end
148151

test/solid_queue_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,18 @@ class SolidQueueTest < ActiveSupport::TestCase
4040
assert_not SolidQueue::RecurringTask.exists?(key: "dynamic", static: false)
4141
assert SolidQueue::RecurringTask.exists?(key: "static", static: true)
4242
end
43+
44+
test "schedule_task with duplicate key raises error" do
45+
SolidQueue.schedule_task("duplicate_test", command: "puts 1", schedule: "every hour")
46+
47+
assert_raises(ActiveRecord::RecordNotUnique) do
48+
SolidQueue.schedule_task("duplicate_test", command: "puts 2", schedule: "every minute")
49+
end
50+
end
51+
52+
test "unschedule_task with nonexistent key raises RecordNotFound" do
53+
assert_raises(ActiveRecord::RecordNotFound) do
54+
SolidQueue.unschedule_task("nonexistent_key")
55+
end
56+
end
4357
end

test/unit/scheduler_test.rb

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ class SchedulerTest < ActiveSupport::TestCase
8181
scheduler = SolidQueue::Scheduler.new(recurring_tasks: {}, polling_interval: 0.1).tap(&:start)
8282

8383
wait_for_registered_processes(1, timeout: 1.second)
84-
sleep 2
84+
wait_while_with_timeout(3.seconds) { SolidQueue::Job.count < 1 }
8585

86-
assert SolidQueue::Job.count >= 1, "Expected at least one job to be enqueued by the dynamic task"
87-
assert_equal SolidQueue::Job.count, SolidQueue::RecurringExecution.count
86+
skip_active_record_query_cache do
87+
assert SolidQueue::Job.count >= 1, "Expected at least one job to be enqueued by the dynamic task"
88+
assert_equal SolidQueue::Job.count, SolidQueue::RecurringExecution.count
89+
end
8890
ensure
8991
scheduler&.stop
9092
end
@@ -94,54 +96,54 @@ class SchedulerTest < ActiveSupport::TestCase
9496

9597
wait_for_registered_processes(1, timeout: 1.second)
9698

97-
process = SolidQueue::Process.first
98-
# initially there are no recurring_schedule keys
99-
assert_empty process.metadata
100-
101-
# now create a dynamic task after the scheduler has booted
102-
SolidQueue::RecurringTask.create(
103-
key: "new_dynamic_task",
104-
static: false,
105-
class_name: "AddToBufferJob",
106-
schedule: "every second",
107-
arguments: [ 42 ]
108-
)
109-
110-
sleep 1
111-
112-
process.reload
113-
114-
# metadata should now include the new key
115-
assert_metadata process, recurring_schedule: [ "new_dynamic_task" ]
99+
skip_active_record_query_cache do
100+
process = SolidQueue::Process.first
101+
# initially there are no recurring_schedule keys
102+
assert_empty process.metadata
103+
104+
# now create a dynamic task after the scheduler has booted
105+
SolidQueue::RecurringTask.create!(
106+
key: "new_dynamic_task",
107+
static: false,
108+
class_name: "AddToBufferJob",
109+
schedule: "every second",
110+
arguments: [ 42 ]
111+
)
112+
113+
wait_while_with_timeout(3.seconds) { process.reload.metadata.empty? }
114+
115+
# metadata should now include the new key
116+
assert_metadata process, recurring_schedule: [ "new_dynamic_task" ]
117+
end
116118
ensure
117119
scheduler&.stop
118120
end
119121

120122
test "updates metadata after removing dynamic task post-start" do
121-
old_dynamic_task = SolidQueue::RecurringTask.create(
122-
key: "old_dynamic_task",
123-
static: false,
123+
old_dynamic_task = SolidQueue::RecurringTask.create!(
124+
key: "old_dynamic_task",
125+
static: false,
124126
class_name: "AddToBufferJob",
125-
schedule: "every second",
126-
arguments: [ 42 ]
127+
schedule: "every second",
128+
arguments: [ 42 ]
127129
)
128130

129131
scheduler = SolidQueue::Scheduler.new(recurring_tasks: {}, polling_interval: 0.1).tap(&:start)
130132

131133
wait_for_registered_processes(1, timeout: 1.second)
132134

133-
process = SolidQueue::Process.first
134-
# initially there is one recurring_schedule key
135-
assert_metadata process, recurring_schedule: [ "old_dynamic_task" ]
136-
137-
old_dynamic_task.destroy
135+
skip_active_record_query_cache do
136+
process = SolidQueue::Process.first
137+
# initially there is one recurring_schedule key
138+
assert_metadata process, recurring_schedule: [ "old_dynamic_task" ]
138139

139-
sleep 1
140+
old_dynamic_task.destroy
140141

141-
process.reload
142+
wait_while_with_timeout(3.seconds) { process.reload.metadata.present? }
142143

143-
# The task is unscheduled after it's been removed, and it's reflected in the metadata
144-
assert_empty process.metadata
144+
# The task is unscheduled after it's been removed, and it's reflected in the metadata
145+
assert_empty process.metadata
146+
end
145147
ensure
146148
scheduler&.stop
147149
end

0 commit comments

Comments
 (0)