hirefire-resource 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/hirefire/macro/bunny.rb +10 -0
- data/lib/hirefire/macro/good_job.rb +2 -0
- data/lib/hirefire/macro/helpers/good_job.rb +15 -0
- data/lib/hirefire/macro/sidekiq.rb +81 -76
- data/lib/hirefire/version.rb +1 -1
- metadata +3 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2472f4d981a95c1869a29eaa7b97429aa2f9f5d8e2a4e1858a167bfc916daee4
|
4
|
+
data.tar.gz: c97478c3f7632dc6ea0c514d6f34894ea0514a1f259c9685e62ed3a63bbba6af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2dc43ce87ea0435294d7f86d44a5e99a30e1a913d170fafadcd7292d061c9a8acdc3a9e3646467d789d32aa83becc40ee89a2b2048136e1badf993f4f9e3e25f
|
7
|
+
data.tar.gz: 90e56a5fdddeb1fdb98f891614fdb6cd66b7a6d07c6efd000ced14cb73de9aa44682d4772b6c4c12c1e114271b57600c7f578cb2a9439d79386d42fa2080d1e4
|
data/CHANGELOG.md
CHANGED
data/lib/hirefire/macro/bunny.rb
CHANGED
@@ -25,6 +25,16 @@ module HireFire
|
|
25
25
|
# with the accurate counting of jobs that are currently scheduled to run, leading to
|
26
26
|
# premature upscaling. If you want to be able to schedule jobs to run in the future,
|
27
27
|
# consider using the Delayed Message Plugin for RabbitMQ.
|
28
|
+
#
|
29
|
+
# @note The method relies on the `message_count` metric to determine the number of "Ready" messages
|
30
|
+
# in the queue. When using auto-acknowledgment, messages are acknowledged immediately upon delivery,
|
31
|
+
# causing the `message_count` to drop to zero, even if the consumer is processing messages. To ensure
|
32
|
+
# accurate metrics:
|
33
|
+
# - Enable manual acknowledgment (`manual_ack: true`) so that RabbitMQ tracks unacknowledged messages.
|
34
|
+
# - Set a reasonable prefetch limit (`channel.prefetch(x)`) to control the number of messages delivered
|
35
|
+
# to the consumer, allowing a measurable backlog to remain in the "Ready" state.
|
36
|
+
# This configuration ensures accurate scaling metrics and prevents premature depletion of the queue.
|
37
|
+
#
|
28
38
|
# @param queues [Array<String, Symbol>] Names of the queues for size measurement.
|
29
39
|
# @param amqp_url [String, nil] (optional) RabbitMQ URL for establishing a new connection.
|
30
40
|
# @return [Integer] Total job queue size.
|
@@ -28,6 +28,7 @@ module HireFire
|
|
28
28
|
query = good_job_class
|
29
29
|
query = query.where(queue_name: queues) if queues.any?
|
30
30
|
query = query.where(performed_at: nil)
|
31
|
+
query = query.where.not(error_event: discarded_enum).or(query.where(error_event: nil)) if error_event_supported?
|
31
32
|
query = query.where(scheduled_at: ..Time.now).or(query.where(scheduled_at: nil))
|
32
33
|
query = query.order(scheduled_at: :asc, created_at: :asc)
|
33
34
|
|
@@ -55,6 +56,7 @@ module HireFire
|
|
55
56
|
query = good_job_class
|
56
57
|
query = query.where(queue_name: queues) if queues.any?
|
57
58
|
query = query.where(performed_at: nil)
|
59
|
+
query = query.where.not(error_event: discarded_enum).or(query.where(error_event: nil)) if error_event_supported?
|
58
60
|
query = query.where(scheduled_at: ..Time.now).or(query.where(scheduled_at: nil))
|
59
61
|
query.count
|
60
62
|
end
|
@@ -13,6 +13,21 @@ module HireFire
|
|
13
13
|
::GoodJob::Execution
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
def error_event_supported?
|
18
|
+
Gem::Version.new(::GoodJob::VERSION) >= Gem::Version.new("3.0.0")
|
19
|
+
end
|
20
|
+
|
21
|
+
[
|
22
|
+
:interrupted,
|
23
|
+
:unhandled,
|
24
|
+
:handled,
|
25
|
+
:retried,
|
26
|
+
:retry_stopped,
|
27
|
+
:discarded
|
28
|
+
].each_with_index do |event, index|
|
29
|
+
define_method(:"#{event}_enum") { index }
|
30
|
+
end
|
16
31
|
end
|
17
32
|
end
|
18
33
|
end
|
@@ -128,10 +128,15 @@ module HireFire
|
|
128
128
|
|
129
129
|
max_latencies = oldest_jobs.map do |job_payload|
|
130
130
|
job = job_payload ? JSON.parse(job_payload) : {}
|
131
|
-
|
131
|
+
|
132
|
+
if Gem::Version.new(::Sidekiq::VERSION) >= Gem::Version.new("8.0.0")
|
133
|
+
job["enqueued_at"] ? Time.now.to_i - job["enqueued_at"] / 1000 : 0
|
134
|
+
else
|
135
|
+
job["enqueued_at"] ? Time.now.to_f - job["enqueued_at"] : 0.0
|
136
|
+
end
|
132
137
|
end
|
133
138
|
|
134
|
-
max_latencies.max || 0
|
139
|
+
Integer(max_latencies.max || 0)
|
135
140
|
end
|
136
141
|
|
137
142
|
def set_latency(set, queues)
|
@@ -157,80 +162,6 @@ module HireFire
|
|
157
162
|
extend HireFire::Utility
|
158
163
|
extend self
|
159
164
|
|
160
|
-
def call(*queues, server: false, **options)
|
161
|
-
require "sidekiq/api"
|
162
|
-
|
163
|
-
queues = normalize_queues(queues, allow_empty: true)
|
164
|
-
|
165
|
-
if server
|
166
|
-
server_lookup(queues, **options)
|
167
|
-
else
|
168
|
-
client_lookup(queues, **options)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
private
|
173
|
-
|
174
|
-
def client_lookup(queues, skip_retries: false, skip_scheduled: false, skip_working: false, max_scheduled: nil)
|
175
|
-
size = enqueued_size(queues)
|
176
|
-
size += scheduled_size(queues, max_scheduled) unless skip_scheduled
|
177
|
-
size += retry_size(queues) unless skip_retries
|
178
|
-
size += working_size(queues) unless skip_working
|
179
|
-
size
|
180
|
-
end
|
181
|
-
|
182
|
-
def enqueued_size(queues)
|
183
|
-
queues = registered_queues if queues.empty?
|
184
|
-
|
185
|
-
::Sidekiq.redis do |conn|
|
186
|
-
conn.pipelined do |pipeline|
|
187
|
-
queues.each { |name| pipeline.llen("queue:#{name}") }
|
188
|
-
end
|
189
|
-
end.sum
|
190
|
-
end
|
191
|
-
|
192
|
-
def scheduled_size(queues, max = nil)
|
193
|
-
size, now = 0, Time.now
|
194
|
-
|
195
|
-
find_each_in_set(::Sidekiq::ScheduledSet.new) do |job|
|
196
|
-
if job.at > now || max && size >= max
|
197
|
-
break
|
198
|
-
elsif queues.empty? || queues.include?(job["queue"])
|
199
|
-
size += 1
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
size
|
204
|
-
end
|
205
|
-
|
206
|
-
def retry_size(queues)
|
207
|
-
size = 0
|
208
|
-
now = Time.now
|
209
|
-
|
210
|
-
find_each_in_set(::Sidekiq::RetrySet.new) do |job|
|
211
|
-
if job.at > now
|
212
|
-
break
|
213
|
-
elsif queues.empty? || queues.include?(job["queue"])
|
214
|
-
size += 1
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
size
|
219
|
-
end
|
220
|
-
|
221
|
-
def working_size(queues)
|
222
|
-
now = Time.now
|
223
|
-
now_as_i = now.to_i
|
224
|
-
|
225
|
-
::Sidekiq::Workers.new.count do |key, tid, job|
|
226
|
-
if job.is_a?(Hash) # Sidekiq < 7.2.1
|
227
|
-
(queues.empty? || queues.include?(job["queue"])) && job["run_at"] <= now_as_i
|
228
|
-
else # Sidekiq >= 7.2.1
|
229
|
-
(queues.empty? || queues.include?(job.queue)) && job.run_at <= now
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
165
|
SERVER_SIDE_SCRIPT = <<~LUA
|
235
166
|
local tonumber = tonumber
|
236
167
|
local cjson_decode = cjson.decode
|
@@ -330,6 +261,80 @@ module HireFire
|
|
330
261
|
|
331
262
|
SERVER_SIDE_SCRIPT_SHA = Digest::SHA1.hexdigest(SERVER_SIDE_SCRIPT).freeze
|
332
263
|
|
264
|
+
def call(*queues, server: false, **options)
|
265
|
+
require "sidekiq/api"
|
266
|
+
|
267
|
+
queues = normalize_queues(queues, allow_empty: true)
|
268
|
+
|
269
|
+
if server
|
270
|
+
server_lookup(queues, **options)
|
271
|
+
else
|
272
|
+
client_lookup(queues, **options)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
private
|
277
|
+
|
278
|
+
def client_lookup(queues, skip_retries: false, skip_scheduled: false, skip_working: false, max_scheduled: nil)
|
279
|
+
size = enqueued_size(queues)
|
280
|
+
size += scheduled_size(queues, max_scheduled) unless skip_scheduled
|
281
|
+
size += retry_size(queues) unless skip_retries
|
282
|
+
size += working_size(queues) unless skip_working
|
283
|
+
size
|
284
|
+
end
|
285
|
+
|
286
|
+
def enqueued_size(queues)
|
287
|
+
queues = registered_queues if queues.empty?
|
288
|
+
|
289
|
+
::Sidekiq.redis do |conn|
|
290
|
+
conn.pipelined do |pipeline|
|
291
|
+
queues.each { |name| pipeline.llen("queue:#{name}") }
|
292
|
+
end
|
293
|
+
end.sum
|
294
|
+
end
|
295
|
+
|
296
|
+
def scheduled_size(queues, max = nil)
|
297
|
+
size, now = 0, Time.now
|
298
|
+
|
299
|
+
find_each_in_set(::Sidekiq::ScheduledSet.new) do |job|
|
300
|
+
if job.at > now || max && size >= max
|
301
|
+
break
|
302
|
+
elsif queues.empty? || queues.include?(job["queue"])
|
303
|
+
size += 1
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
size
|
308
|
+
end
|
309
|
+
|
310
|
+
def retry_size(queues)
|
311
|
+
size = 0
|
312
|
+
now = Time.now
|
313
|
+
|
314
|
+
find_each_in_set(::Sidekiq::RetrySet.new) do |job|
|
315
|
+
if job.at > now
|
316
|
+
break
|
317
|
+
elsif queues.empty? || queues.include?(job["queue"])
|
318
|
+
size += 1
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
size
|
323
|
+
end
|
324
|
+
|
325
|
+
def working_size(queues)
|
326
|
+
now = Time.now
|
327
|
+
now_as_i = now.to_i
|
328
|
+
|
329
|
+
::Sidekiq::Workers.new.count do |key, tid, job|
|
330
|
+
if job.is_a?(Hash) # Sidekiq < 7.2.1
|
331
|
+
(queues.empty? || queues.include?(job["queue"])) && job["run_at"] <= now_as_i
|
332
|
+
else # Sidekiq >= 7.2.1
|
333
|
+
(queues.empty? || queues.include?(job.queue)) && job.run_at <= now
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
333
338
|
def server_lookup(queues, skip_scheduled: false, skip_retries: false, skip_working: false, max_scheduled: 0)
|
334
339
|
::Sidekiq.redis do |connection|
|
335
340
|
now = Time.now.to_i
|
data/lib/hirefire/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hirefire-resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael van Rooijen
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-24 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: appraisal
|
@@ -24,7 +23,6 @@ dependencies:
|
|
24
23
|
- - "~>"
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: '2'
|
27
|
-
description:
|
28
26
|
email:
|
29
27
|
- support@hirefire.io
|
30
28
|
executables: []
|
@@ -72,7 +70,6 @@ metadata:
|
|
72
70
|
changelog_uri: https://github.com/hirefire/hirefire-resource-ruby/blob/master/CHANGELOG.md
|
73
71
|
source_code_uri: https://github.com/hirefire/hirefire-resource-ruby
|
74
72
|
bug_tracker_uri: https://github.com/hirefire/hirefire-resource-ruby/issues
|
75
|
-
post_install_message:
|
76
73
|
rdoc_options: []
|
77
74
|
require_paths:
|
78
75
|
- lib
|
@@ -87,8 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
84
|
- !ruby/object:Gem::Version
|
88
85
|
version: '0'
|
89
86
|
requirements: []
|
90
|
-
rubygems_version: 3.
|
91
|
-
signing_key:
|
87
|
+
rubygems_version: 3.6.2
|
92
88
|
specification_version: 4
|
93
89
|
summary: HireFire integration library for Ruby applications
|
94
90
|
test_files: []
|