Skip to content

Commit

Permalink
Avoid replacing executions when moving jobs between states
Browse files Browse the repository at this point in the history
That is, when using `create_*_execution!` from job, if the job previously
had a record for that, we'd create a new one and replace it. This causes
problems with Mission Control when a thread dies taking care of a job and
leaves it in a weird, in-between state.
  • Loading branch information
rosa committed Sep 15, 2023
1 parent 2b9057d commit 46f2d7e
Showing 1 changed file with 40 additions and 38 deletions.
78 changes: 40 additions & 38 deletions app/models/solid_queue/job/executable.rb
Original file line number Diff line number Diff line change
@@ -1,52 +1,54 @@
module SolidQueue::Job::Executable
extend ActiveSupport::Concern
module SolidQueue
module Job::Executable
extend ActiveSupport::Concern

included do
has_one :ready_execution, dependent: :destroy
has_one :claimed_execution, dependent: :destroy
has_one :failed_execution, dependent: :destroy
included do
has_one :ready_execution, dependent: :destroy
has_one :claimed_execution, dependent: :destroy
has_one :failed_execution, dependent: :destroy

has_one :scheduled_execution, dependent: :destroy
has_one :scheduled_execution, dependent: :destroy

after_create :prepare_for_execution
end
after_create :prepare_for_execution
end

STATUSES = %w[ ready claimed failed scheduled ]
STATUSES = %w[ ready claimed failed scheduled ]

STATUSES.each do |status|
define_method("#{status}?") { public_send("#{status}_execution").present? }
end

def prepare_for_execution
if due?
create_ready_execution!
else
create_scheduled_execution!
STATUSES.each do |status|
define_method("#{status}?") { public_send("#{status}_execution").present? }
end
end

def finished
touch(:finished_at)
end
def prepare_for_execution
if due?
ReadyExecution.create_or_find_by!(job_id: id)
else
ScheduledExecution.create_or_find_by!(job_id: id)
end
end

def finished?
finished_at.present?
end
def finished
touch(:finished_at)
end

def failed_with(exception)
create_failed_execution!(exception: exception)
end
def finished?
finished_at.present?
end

def discard
destroy unless claimed?
end
def failed_with(exception)
FailedExecution.create_or_find_by!(job_id: id, exception: exception)
end

def retry
failed_execution&.retry
end
def discard
destroy unless claimed?
end

private
def due?
scheduled_at.nil? || scheduled_at <= Time.current
def retry
failed_execution&.retry
end

private
def due?
scheduled_at.nil? || scheduled_at <= Time.current
end
end
end

0 comments on commit 46f2d7e

Please sign in to comment.