Skip to content

Commit 61fec0d

Browse files
committed
Use intermediate Proxy object for the Semaphore low-level actions
Building on a suggestion from @jorgemanrubia.
1 parent ed30280 commit 61fec0d

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

app/models/solid_queue/semaphore.rb

+41-12
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,60 @@ class SolidQueue::Semaphore < SolidQueue::Record
44

55
class << self
66
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
924
else
10-
attempt_creation(job.concurrency_key, job.concurrency_limit, job.concurrency_duration)
25+
attempt_creation
1126
end
1227
end
1328

14-
def signal(job)
15-
attempt_increment(job.concurrency_key, job.concurrency_limit, job.concurrency_duration)
29+
def signal
30+
attempt_increment
1631
end
1732

1833
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)
2138
true
2239
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
2453
end
2554

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
2857
end
2958

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
3261
end
3362
end
3463
end

0 commit comments

Comments
 (0)