File tree Expand file tree Collapse file tree 5 files changed +53
-13
lines changed Expand file tree Collapse file tree 5 files changed +53
-13
lines changed Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ def self.retry_all(jobs)
2121 def retry
2222 SolidQueue . instrument ( :retry , job_id : job . id ) do
2323 with_lock do
24+ job . reset_execution_counters
2425 job . prepare_for_execution
2526 destroy!
2627 end
Original file line number Diff line number Diff line change @@ -6,16 +6,14 @@ module Executable
66 extend ActiveSupport ::Concern
77
88 included do
9- include ConcurrencyControls , Schedulable
9+ include ConcurrencyControls , Schedulable , Retryable
1010
1111 has_one :ready_execution
1212 has_one :claimed_execution
13- has_one :failed_execution
1413
1514 after_create :prepare_for_execution
1615
1716 scope :finished , -> { where . not ( finished_at : nil ) }
18- scope :failed , -> { includes ( :failed_execution ) . where . not ( failed_execution : { id : nil } ) }
1917 end
2018
2119 class_methods do
@@ -97,18 +95,10 @@ def status
9795 end
9896 end
9997
100- def retry
101- failed_execution &.retry
102- end
103-
10498 def discard
10599 execution &.discard
106100 end
107101
108- def failed_with ( exception )
109- FailedExecution . create_or_find_by! ( job_id : id , exception : exception )
110- end
111-
112102 private
113103 def ready
114104 ReadyExecution . create_or_find_by! ( job_id : id )
Original file line number Diff line number Diff line change 1+ # frozen_string_literal: true
2+
3+ module SolidQueue
4+ class Job
5+ module Retryable
6+ extend ActiveSupport ::Concern
7+
8+ included do
9+ has_one :failed_execution
10+
11+ scope :failed , -> { includes ( :failed_execution ) . where . not ( failed_execution : { id : nil } ) }
12+ end
13+
14+ def retry
15+ failed_execution &.retry
16+ end
17+
18+ def failed_with ( exception )
19+ FailedExecution . create_or_find_by! ( job_id : id , exception : exception )
20+ end
21+
22+ def reset_execution_counters
23+ arguments [ "executions" ] = 0
24+ arguments [ "exception_executions" ] = { }
25+ save!
26+ end
27+ end
28+ end
29+ end
Original file line number Diff line number Diff line change @@ -7,10 +7,10 @@ class DiscardableError < StandardError; end
77 retry_on DefaultError , attempts : 3 , wait : 0.1 . seconds
88 discard_on DiscardableError
99
10- def perform ( raising , identifier , attempts = 1 )
10+ def perform ( raising , identifier , fail_count = 1 )
1111 raising = raising . shift if raising . is_a? ( Array )
1212
13- if raising && executions <= attempts
13+ if raising && executions <= fail_count
1414 JobBuffer . add ( "#{ identifier } : raised #{ raising } for the #{ executions . ordinalize } time" )
1515 raise raising , "This is a #{ raising } exception"
1616 else
Original file line number Diff line number Diff line change @@ -62,6 +62,26 @@ class JobsLifecycleTest < ActiveSupport::TestCase
6262 assert_equal 1 , SolidQueue ::FailedExecution . count
6363 end
6464
65+ test "retry job that failed after being automatically retried" do
66+ RaisingJob . perform_later ( RaisingJob ::DefaultError , "A" , 5 )
67+
68+ @dispatcher . start
69+ @worker . start
70+
71+ wait_for_jobs_to_finish_for ( 3 . seconds )
72+
73+ assert_equal 2 , SolidQueue ::Job . finished . count # 2 retries of A
74+ assert_equal 1 , SolidQueue ::FailedExecution . count
75+
76+ failed_execution = SolidQueue ::FailedExecution . last
77+ failed_execution . job . retry
78+
79+ wait_for_jobs_to_finish_for ( 3 . seconds )
80+
81+ assert_equal 4 , SolidQueue ::Job . finished . count # Add other 2 retries of A
82+ assert_equal 1 , SolidQueue ::FailedExecution . count
83+ end
84+
6585 test "enqueue and run jobs that fail and it's discarded" do
6686 RaisingJob . perform_later ( RaisingJob ::DiscardableError , "A" )
6787
You can’t perform that action at this time.
0 commit comments