File tree 5 files changed +53
-13
lines changed
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)
21
21
def retry
22
22
SolidQueue . instrument ( :retry , job_id : job . id ) do
23
23
with_lock do
24
+ job . reset_execution_counters
24
25
job . prepare_for_execution
25
26
destroy!
26
27
end
Original file line number Diff line number Diff line change @@ -6,16 +6,14 @@ module Executable
6
6
extend ActiveSupport ::Concern
7
7
8
8
included do
9
- include ConcurrencyControls , Schedulable
9
+ include ConcurrencyControls , Schedulable , Retryable
10
10
11
11
has_one :ready_execution
12
12
has_one :claimed_execution
13
- has_one :failed_execution
14
13
15
14
after_create :prepare_for_execution
16
15
17
16
scope :finished , -> { where . not ( finished_at : nil ) }
18
- scope :failed , -> { includes ( :failed_execution ) . where . not ( failed_execution : { id : nil } ) }
19
17
end
20
18
21
19
class_methods do
@@ -97,18 +95,10 @@ def status
97
95
end
98
96
end
99
97
100
- def retry
101
- failed_execution &.retry
102
- end
103
-
104
98
def discard
105
99
execution &.discard
106
100
end
107
101
108
- def failed_with ( exception )
109
- FailedExecution . create_or_find_by! ( job_id : id , exception : exception )
110
- end
111
-
112
102
private
113
103
def ready
114
104
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
7
7
retry_on DefaultError , attempts : 3 , wait : 0.1 . seconds
8
8
discard_on DiscardableError
9
9
10
- def perform ( raising , identifier , attempts = 1 )
10
+ def perform ( raising , identifier , fail_count = 1 )
11
11
raising = raising . shift if raising . is_a? ( Array )
12
12
13
- if raising && executions <= attempts
13
+ if raising && executions <= fail_count
14
14
JobBuffer . add ( "#{ identifier } : raised #{ raising } for the #{ executions . ordinalize } time" )
15
15
raise raising , "This is a #{ raising } exception"
16
16
else
Original file line number Diff line number Diff line change @@ -62,6 +62,26 @@ class JobsLifecycleTest < ActiveSupport::TestCase
62
62
assert_equal 1 , SolidQueue ::FailedExecution . count
63
63
end
64
64
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
+
65
85
test "enqueue and run jobs that fail and it's discarded" do
66
86
RaisingJob . perform_later ( RaisingJob ::DiscardableError , "A" )
67
87
You can’t perform that action at this time.
0 commit comments