@@ -4,31 +4,60 @@ class SolidQueue::Semaphore < SolidQueue::Record
4
4
5
5
class << self
6
6
def wait ( job )
7
- if semaphore = find_by ( key : job . concurrency_key )
8
- semaphore . value > 0 && attempt_decrement ( job . concurrency_key , job . concurrency_duration )
7
+ Proxy . new ( job , self ) . wait
8
+ end
9
+
10
+ def signal ( job )
11
+ Proxy . new ( job , self ) . signal
12
+ end
13
+ end
14
+
15
+ class Proxy
16
+ def initialize ( job , proxied_class )
17
+ @job = job
18
+ @proxied_class = proxied_class
19
+ end
20
+
21
+ def wait
22
+ if semaphore = proxied_class . find_by ( key : key )
23
+ semaphore . value > 0 && attempt_decrement
9
24
else
10
- attempt_creation ( job . concurrency_key , job . concurrency_limit , job . concurrency_duration )
25
+ attempt_creation
11
26
end
12
27
end
13
28
14
- def signal ( job )
15
- attempt_increment ( job . concurrency_key , job . concurrency_limit , job . concurrency_duration )
29
+ def signal
30
+ attempt_increment
16
31
end
17
32
18
33
private
19
- def attempt_creation ( key , limit , duration )
20
- create! ( key : key , value : limit - 1 , expires_at : duration . from_now )
34
+ attr_reader :job , :proxied_class
35
+
36
+ def attempt_creation
37
+ proxied_class . create! ( key : key , value : limit - 1 , expires_at : expires_at )
21
38
true
22
39
rescue ActiveRecord ::RecordNotUnique
23
- attempt_decrement ( key , duration )
40
+ attempt_decrement
41
+ end
42
+
43
+ def attempt_decrement
44
+ proxied_class . available . where ( key : key ) . update_all ( [ "value = value - 1, expires_at = ?" , expires_at ] ) > 0
45
+ end
46
+
47
+ def attempt_increment
48
+ proxied_class . where ( key : key , value : ...limit ) . update_all ( [ "value = value + 1, expires_at = ?" , expires_at ] ) > 0
49
+ end
50
+
51
+ def key
52
+ job . concurrency_key
24
53
end
25
54
26
- def attempt_decrement ( key , duration )
27
- available . where ( key : key ) . update_all ( [ "value = value - 1, expires_at = ?" , duration . from_now ] ) > 0
55
+ def expires_at
56
+ job . concurrency_duration . from_now
28
57
end
29
58
30
- def attempt_increment ( key , limit , duration )
31
- where ( "value < ?" , limit ) . where ( key : key ) . update_all ( [ "value = value + 1, expires_at = ?" , duration . from_now ] ) > 0
59
+ def limit
60
+ job . concurrency_limit
32
61
end
33
62
end
34
63
end
0 commit comments