Skip to content

Commit

Permalink
Support recurring jobs that defer enqueuing to after commit always
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rosa committed Aug 21, 2024
1 parent 89d30c7 commit 0c81c77
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/models/solid_queue/recurring_execution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def create_or_insert!(**attributes)
def record(task_key, run_at, &block)
transaction do
block.call.tap do |active_job|
if active_job
if active_job && active_job.successfully_enqueued?
create_or_insert!(job_id: active_job.provider_job_id, task_key: task_key, run_at: run_at)
end
end
Expand Down
13 changes: 10 additions & 3 deletions app/models/solid_queue/recurring_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def next_time
def enqueue(at:)
SolidQueue.instrument(:enqueue_recurring_task, task: key, at: at) do |payload|
active_job = if using_solid_queue_adapter?
perform_later_and_record(run_at: at)
enqueue_and_record(run_at: at)
else
payload[:other_adapter] = true

Expand Down Expand Up @@ -87,8 +87,15 @@ def using_solid_queue_adapter?
job_class.queue_adapter_name.inquiry.solid_queue?
end

def perform_later_and_record(run_at:)
RecurringExecution.record(key, run_at) { perform_later }
def enqueue_and_record(run_at:)
RecurringExecution.record(key, run_at) do
job_class.new(*arguments_with_kwargs).tap do |active_job|
active_job.run_callbacks(:enqueue) do
Job.enqueue(active_job)
end
active_job.successfully_enqueued = true
end
end
end

def perform_later(&block)
Expand Down

0 comments on commit 0c81c77

Please sign in to comment.