File tree Expand file tree Collapse file tree 3 files changed +33
-5
lines changed Expand file tree Collapse file tree 3 files changed +33
-5
lines changed Original file line number Diff line number Diff line change 171
171
172
172
PLATFORMS
173
173
arm64-darwin-22
174
+ arm64-darwin-23
174
175
x86_64-darwin-21
175
176
x86_64-darwin-23
176
177
x86_64-linux
Original file line number Diff line number Diff line change @@ -17,6 +17,17 @@ def signal(job)
17
17
def signal_all ( jobs )
18
18
Proxy . signal_all ( jobs )
19
19
end
20
+
21
+ # Requires a unique index on key
22
+ def create_unique_by ( attributes )
23
+ if connection . supports_insert_conflict_target?
24
+ insert ( { **attributes } , unique_by : :key ) . any?
25
+ else
26
+ create! ( **attributes )
27
+ end
28
+ rescue ActiveRecord ::RecordNotUnique
29
+ false
30
+ end
20
31
end
21
32
22
33
class Proxy
@@ -41,18 +52,19 @@ def signal
41
52
end
42
53
43
54
private
55
+
44
56
attr_accessor :job
45
57
46
58
def attempt_creation
47
- Semaphore . create! ( key : key , value : limit - 1 , expires_at : expires_at )
48
- true
49
- rescue ActiveRecord ::RecordNotUnique
50
- if limit == 1 then false
59
+ if Semaphore . create_unique_by ( key : key , value : limit - 1 , expires_at : expires_at )
60
+ true
51
61
else
52
- attempt_decrement
62
+ check_limit_or_decrement
53
63
end
54
64
end
55
65
66
+ def check_limit_or_decrement = limit == 1 ? false : attempt_decrement
67
+
56
68
def attempt_decrement
57
69
Semaphore . available . where ( key : key ) . update_all ( [ "value = value - 1, expires_at = ?" , expires_at ] ) > 0
58
70
end
Original file line number Diff line number Diff line change @@ -183,7 +183,22 @@ class ConcurrencyControlsTest < ActiveSupport::TestCase
183
183
assert job . reload . ready?
184
184
end
185
185
186
+ test "verify transactions remain valid after Job creation conflicts via limits_concurrency" do
187
+ ActiveRecord ::Base . transaction do
188
+ SequentialUpdateResultJob . perform_later ( @result , name : "A" , pause : 0.2 . seconds )
189
+ SequentialUpdateResultJob . perform_later ( @result , name : "B" )
190
+
191
+ begin
192
+ assert_equal 2 , SolidQueue ::Job . count
193
+ assert true , "Transaction state valid"
194
+ rescue ActiveRecord ::StatementInvalid
195
+ assert false , "Transaction state unexpectedly invalid"
196
+ end
197
+ end
198
+ end
199
+
186
200
private
201
+
187
202
def assert_stored_sequence ( result , *sequences )
188
203
expected = sequences . map { |sequence | "seq: " + sequence . map { |name | "s#{ name } c#{ name } " } . join }
189
204
skip_active_record_query_cache do
You can’t perform that action at this time.
0 commit comments