Skip to content

Commit 0c81c77

Browse files
committed
Support recurring jobs that defer enqueuing to after commit always
These need to be enqueued within the transaction that creates the recurring execution to avoid duplicate crons. However, if the job is set to `enqueue_after_transaction_commit = :always` or :default when we change the default, it won't work because we'll try to create the recurring execution without having actually enqueued the job. With this change, we bypass Active Job's enqueuing and enqueue directly with Solid Queue, running enqueue callbacks.
1 parent 89d30c7 commit 0c81c77

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

app/models/solid_queue/recurring_execution.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def create_or_insert!(**attributes)
2525
def record(task_key, run_at, &block)
2626
transaction do
2727
block.call.tap do |active_job|
28-
if active_job
28+
if active_job && active_job.successfully_enqueued?
2929
create_or_insert!(job_id: active_job.provider_job_id, task_key: task_key, run_at: run_at)
3030
end
3131
end

app/models/solid_queue/recurring_task.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def next_time
4343
def enqueue(at:)
4444
SolidQueue.instrument(:enqueue_recurring_task, task: key, at: at) do |payload|
4545
active_job = if using_solid_queue_adapter?
46-
perform_later_and_record(run_at: at)
46+
enqueue_and_record(run_at: at)
4747
else
4848
payload[:other_adapter] = true
4949

@@ -87,8 +87,15 @@ def using_solid_queue_adapter?
8787
job_class.queue_adapter_name.inquiry.solid_queue?
8888
end
8989

90-
def perform_later_and_record(run_at:)
91-
RecurringExecution.record(key, run_at) { perform_later }
90+
def enqueue_and_record(run_at:)
91+
RecurringExecution.record(key, run_at) do
92+
job_class.new(*arguments_with_kwargs).tap do |active_job|
93+
active_job.run_callbacks(:enqueue) do
94+
Job.enqueue(active_job)
95+
end
96+
active_job.successfully_enqueued = true
97+
end
98+
end
9299
end
93100

94101
def perform_later(&block)

0 commit comments

Comments
 (0)