jobba 1.8.1 → 2.0.0
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/.github/workflows/tests.yml +3 -3
- data/jobba.gemspec +17 -18
- data/lib/jobba/common.rb +4 -2
- data/lib/jobba/query.rb +13 -18
- data/lib/jobba/status.rb +72 -68
- data/lib/jobba/statuses.rb +9 -10
- data/lib/jobba/version.rb +1 -1
- data/lib/jobba.rb +33 -16
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fd0ebb186e9eca18861196616b9d2e6518d1193e5672ae68d783762e3a1f6f7
|
4
|
+
data.tar.gz: af77889b9e09fd57d965fe8b8b8c619b13d6b21ce249d7c4d5677f9f537d41ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c1ef1efbc0496d339e79d188a56718b9db416b28e62ac6e247e91ab0c43ce0313e02a7dee103b8cfe1dc034005567a55fd8db1811487c331d2396bc5de555b0
|
7
|
+
data.tar.gz: 668c4722c4bd2505d84cad9860dec70a028acee23d980ce99d67d0969d4e9164ae5d9dca08ef15ec465c226046242429c95e18c3cd94a6e60efabacd5323a2d8
|
data/.github/workflows/tests.yml
CHANGED
@@ -12,12 +12,12 @@ on:
|
|
12
12
|
jobs:
|
13
13
|
tests:
|
14
14
|
timeout-minutes: 30
|
15
|
-
runs-on: ubuntu-
|
15
|
+
runs-on: ubuntu-22.04
|
16
16
|
strategy:
|
17
17
|
fail-fast: false
|
18
18
|
matrix:
|
19
19
|
os: [ubuntu]
|
20
|
-
ruby: [ '2.
|
20
|
+
ruby: [ '2.6', '2.7', '3.0', '3.1' ]
|
21
21
|
services:
|
22
22
|
# Label used to access the service container
|
23
23
|
redis:
|
@@ -32,7 +32,7 @@ jobs:
|
|
32
32
|
# Maps port 6379 on service container to the host
|
33
33
|
- 6379:6379
|
34
34
|
steps:
|
35
|
-
- uses: actions/checkout@
|
35
|
+
- uses: actions/checkout@v3
|
36
36
|
- uses: ruby/setup-ruby@v1
|
37
37
|
with:
|
38
38
|
ruby-version: ${{ matrix.ruby }}
|
data/jobba.gemspec
CHANGED
@@ -1,30 +1,29 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'jobba/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'jobba'
|
8
7
|
spec.version = Jobba::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
8
|
+
spec.authors = ['JP Slavinsky']
|
9
|
+
spec.email = ['jps@kindlinglabs.com']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
11
|
+
spec.summary = 'Redis-based background job status tracking.'
|
12
|
+
spec.description = 'Redis-based background job status tracking.'
|
13
|
+
spec.homepage = 'https://github.com/openstax/jobba'
|
14
|
+
spec.license = 'MIT'
|
16
15
|
|
17
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
-
spec.bindir =
|
17
|
+
spec.bindir = 'exe'
|
19
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
21
20
|
|
22
|
-
spec.add_runtime_dependency
|
23
|
-
spec.add_runtime_dependency
|
24
|
-
spec.add_runtime_dependency
|
21
|
+
spec.add_runtime_dependency 'oj'
|
22
|
+
spec.add_runtime_dependency 'redis', '>= 4.0'
|
23
|
+
spec.add_runtime_dependency 'redis-namespace'
|
25
24
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
25
|
+
spec.add_development_dependency 'byebug'
|
26
|
+
spec.add_development_dependency 'fakeredis'
|
27
|
+
spec.add_development_dependency 'rake'
|
28
|
+
spec.add_development_dependency 'rspec'
|
30
29
|
end
|
data/lib/jobba/common.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Jobba::Common
|
2
|
-
|
3
2
|
def redis
|
4
3
|
Jobba.redis
|
5
4
|
end
|
6
5
|
|
6
|
+
def transaction(&block)
|
7
|
+
Jobba.transaction(&block)
|
8
|
+
end
|
9
|
+
|
7
10
|
module ClassMethods
|
8
11
|
def redis
|
9
12
|
Jobba.redis
|
@@ -13,5 +16,4 @@ module Jobba::Common
|
|
13
16
|
def self.included(base)
|
14
17
|
base.extend(ClassMethods)
|
15
18
|
end
|
16
|
-
|
17
19
|
end
|
data/lib/jobba/query.rb
CHANGED
@@ -3,14 +3,13 @@ require 'jobba/id_clause'
|
|
3
3
|
require 'jobba/clause_factory'
|
4
4
|
|
5
5
|
class Jobba::Query
|
6
|
-
|
7
6
|
include Jobba::Common
|
8
7
|
|
9
8
|
attr_reader :_limit, :_offset
|
10
9
|
|
11
10
|
def where(options)
|
12
|
-
options.each do |kk,vv|
|
13
|
-
clauses.push(Jobba::ClauseFactory.new_clause(kk,vv))
|
11
|
+
options.each do |kk, vv|
|
12
|
+
clauses.push(Jobba::ClauseFactory.new_clause(kk, vv))
|
14
13
|
end
|
15
14
|
|
16
15
|
self
|
@@ -72,20 +71,20 @@ class Jobba::Query
|
|
72
71
|
end
|
73
72
|
|
74
73
|
# Standalone method that gives the final result when the query is one clause
|
75
|
-
def handle_single_clause(
|
76
|
-
raise
|
74
|
+
def handle_single_clause(_clause)
|
75
|
+
raise 'AbstractMethod'
|
77
76
|
end
|
78
77
|
|
79
78
|
# When the query is multiple clauses, this method is called on the final set
|
80
79
|
# that represents the ANDing of all clauses. It is called inside a `redis.multi`
|
81
80
|
# block.
|
82
|
-
def multi_clause_last_redis_op(
|
83
|
-
raise
|
81
|
+
def multi_clause_last_redis_op(_result_set)
|
82
|
+
raise 'AbstractMethod'
|
84
83
|
end
|
85
84
|
|
86
85
|
# Called on the output from the redis multi block for multi-clause queries.
|
87
|
-
def multi_clause_postprocess(
|
88
|
-
raise
|
86
|
+
def multi_clause_postprocess(_redis_output)
|
87
|
+
raise 'AbstractMethod'
|
89
88
|
end
|
90
89
|
end
|
91
90
|
|
@@ -121,9 +120,7 @@ class Jobba::Query
|
|
121
120
|
end
|
122
121
|
|
123
122
|
def _run(operations)
|
124
|
-
if _limit.nil? && !_offset.nil?
|
125
|
-
raise ArgumentError, "`limit` must be set if `offset` is set", caller
|
126
|
-
end
|
123
|
+
raise ArgumentError, '`limit` must be set if `offset` is set', caller if _limit.nil? && !_offset.nil?
|
127
124
|
|
128
125
|
load_default_clause if clauses.empty?
|
129
126
|
|
@@ -145,8 +142,7 @@ class Jobba::Query
|
|
145
142
|
#
|
146
143
|
# This code also works for the single clause case, but it is less efficient
|
147
144
|
|
148
|
-
multi_result =
|
149
|
-
|
145
|
+
multi_result = transaction do |trn|
|
150
146
|
working_set = nil
|
151
147
|
|
152
148
|
clauses.each do |clause|
|
@@ -155,15 +151,15 @@ class Jobba::Query
|
|
155
151
|
if working_set.nil?
|
156
152
|
working_set = clause_set
|
157
153
|
else
|
158
|
-
|
159
|
-
|
154
|
+
trn.zinterstore(working_set, [working_set, clause_set], weights: [0, 0])
|
155
|
+
trn.del(clause_set)
|
160
156
|
end
|
161
157
|
end
|
162
158
|
|
163
159
|
# This is later accessed as `multi_result[-2]` since it is the second to last output
|
164
160
|
operations.multi_clause_last_redis_op(working_set)
|
165
161
|
|
166
|
-
|
162
|
+
trn.del(working_set)
|
167
163
|
end
|
168
164
|
|
169
165
|
operations.multi_clause_postprocess(multi_result[-2])
|
@@ -173,5 +169,4 @@ class Jobba::Query
|
|
173
169
|
def load_default_clause
|
174
170
|
where(state: Jobba::State::ALL.collect(&:name))
|
175
171
|
end
|
176
|
-
|
177
172
|
end
|
data/lib/jobba/status.rb
CHANGED
@@ -3,7 +3,6 @@ require 'oj'
|
|
3
3
|
|
4
4
|
module Jobba
|
5
5
|
class Status
|
6
|
-
|
7
6
|
include Jobba::Common
|
8
7
|
|
9
8
|
def self.all
|
@@ -40,8 +39,8 @@ module Jobba
|
|
40
39
|
end
|
41
40
|
|
42
41
|
def self.local_attrs
|
43
|
-
%w
|
44
|
-
|
42
|
+
%w[id state progress errors data kill_requested_at
|
43
|
+
job_name job_args provider_job_id attempt prior_attempts] +
|
45
44
|
State::ALL.collect(&:timestamp_name)
|
46
45
|
end
|
47
46
|
|
@@ -56,7 +55,7 @@ module Jobba
|
|
56
55
|
# As an extra step, convert state names into State objects.
|
57
56
|
|
58
57
|
local_attrs.each do |attribute|
|
59
|
-
class_eval <<-
|
58
|
+
class_eval <<-EORUBY, __FILE__, __LINE__ + 1
|
60
59
|
def #{attribute}
|
61
60
|
@#{attribute} ||= load_from_json_encoded_attrs('#{attribute}')
|
62
61
|
end
|
@@ -64,12 +63,12 @@ module Jobba
|
|
64
63
|
protected
|
65
64
|
|
66
65
|
attr_writer :#{attribute}
|
67
|
-
|
66
|
+
EORUBY
|
68
67
|
end
|
69
68
|
|
70
69
|
State::ENTERABLE.each do |state|
|
71
70
|
define_method("#{state.name}!") do
|
72
|
-
|
71
|
+
transaction do
|
73
72
|
if state == State::STARTED && did_start?
|
74
73
|
restart!
|
75
74
|
elsif state != self.state
|
@@ -96,14 +95,14 @@ module Jobba
|
|
96
95
|
end
|
97
96
|
|
98
97
|
def did_start?
|
99
|
-
!
|
98
|
+
!started_at.nil?
|
100
99
|
end
|
101
100
|
|
102
101
|
def request_kill!
|
103
102
|
time, usec_int = now
|
104
|
-
|
105
|
-
|
106
|
-
|
103
|
+
return unless redis.hsetnx(job_key, :kill_requested_at, usec_int)
|
104
|
+
|
105
|
+
@kill_requested_at = time
|
107
106
|
end
|
108
107
|
|
109
108
|
def kill_requested?
|
@@ -116,24 +115,26 @@ module Jobba
|
|
116
115
|
end
|
117
116
|
|
118
117
|
def set_job_name(job_name)
|
119
|
-
raise ArgumentError,
|
118
|
+
raise ArgumentError, '`job_name` must not be blank', caller \
|
120
119
|
if job_name.nil? || job_name.empty?
|
121
120
|
|
122
|
-
|
123
|
-
|
121
|
+
transaction do |trn|
|
122
|
+
trn.srem(job_name_key, id)
|
124
123
|
set(job_name: job_name)
|
125
|
-
|
124
|
+
trn.sadd(job_name_key, id)
|
126
125
|
end
|
127
126
|
end
|
128
127
|
|
129
|
-
def set_job_args(args_hash={})
|
130
|
-
|
131
|
-
|
132
|
-
|
128
|
+
def set_job_args(args_hash = {})
|
129
|
+
if args_hash.values.any? { |val| !val.is_a?(String) }
|
130
|
+
raise ArgumentError,
|
131
|
+
'All values in the hash passed to `set_job_args` must be strings',
|
132
|
+
caller
|
133
|
+
end
|
133
134
|
|
134
135
|
args_hash = normalize_for_json(args_hash)
|
135
136
|
|
136
|
-
|
137
|
+
transaction do
|
137
138
|
delete_self_from_job_args_set!
|
138
139
|
set(job_args: args_hash)
|
139
140
|
add_self_to_job_args_set!
|
@@ -141,18 +142,18 @@ module Jobba
|
|
141
142
|
end
|
142
143
|
|
143
144
|
def set_provider_job_id(provider_job_id)
|
144
|
-
raise ArgumentError,
|
145
|
+
raise ArgumentError, '`provider_job_id` must not be blank', caller \
|
145
146
|
if provider_job_id.nil? || (provider_job_id.respond_to?(:empty?) && provider_job_id.empty?)
|
146
147
|
|
147
|
-
|
148
|
-
|
148
|
+
transaction do |trn|
|
149
|
+
trn.srem(provider_job_id_key, id)
|
149
150
|
set(provider_job_id: provider_job_id)
|
150
|
-
|
151
|
+
trn.sadd(provider_job_id_key, id)
|
151
152
|
end
|
152
153
|
end
|
153
154
|
|
154
155
|
def add_error(error)
|
155
|
-
raise ArgumentError,
|
156
|
+
raise ArgumentError, 'The argument to `add_error` cannot be nil', caller if error.nil?
|
156
157
|
|
157
158
|
errors.push(normalize_for_json(error))
|
158
159
|
set(errors: errors)
|
@@ -171,11 +172,13 @@ module Jobba
|
|
171
172
|
end
|
172
173
|
|
173
174
|
def delete
|
174
|
-
completed?
|
175
|
-
delete!
|
176
|
-
|
177
|
-
|
178
|
-
|
175
|
+
if completed?
|
176
|
+
delete!
|
177
|
+
else
|
178
|
+
raise(NotCompletedError, 'This status cannot be deleted because it ' \
|
179
|
+
"isn't complete. Use `delete!` if you want to " \
|
180
|
+
'delete anyway.')
|
181
|
+
end
|
179
182
|
end
|
180
183
|
|
181
184
|
def delete!
|
@@ -184,7 +187,7 @@ module Jobba
|
|
184
187
|
end
|
185
188
|
|
186
189
|
def prior_attempts
|
187
|
-
@prior_attempts ||= [*0..attempt-1].collect{|ii| self.class.find!("#{id}:#{ii}")}
|
190
|
+
@prior_attempts ||= [*0..attempt - 1].collect { |ii| self.class.find!("#{id}:#{ii}") }
|
188
191
|
end
|
189
192
|
|
190
193
|
protected
|
@@ -204,14 +207,14 @@ module Jobba
|
|
204
207
|
|
205
208
|
restarted_values = {
|
206
209
|
id: id,
|
207
|
-
attempt: attempt+1,
|
210
|
+
attempt: attempt + 1,
|
208
211
|
recorded_at: recorded_at,
|
209
212
|
queued_at: queued_at,
|
210
213
|
progress: 0,
|
211
214
|
errors: [],
|
212
215
|
job_name: job_name,
|
213
216
|
job_args: job_args,
|
214
|
-
provider_job_id: provider_job_id
|
217
|
+
provider_job_id: provider_job_id,
|
215
218
|
}
|
216
219
|
|
217
220
|
archive_attempt!
|
@@ -236,29 +239,28 @@ module Jobba
|
|
236
239
|
|
237
240
|
@json_encoded_attrs = attrs[:raw]
|
238
241
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
end
|
242
|
+
return unless @json_encoded_attrs.nil? || @json_encoded_attrs.empty?
|
243
|
+
|
244
|
+
@id = attrs[:id] || SecureRandom.uuid
|
245
|
+
@state = attrs[:state] || State::UNKNOWN
|
246
|
+
@progress = attrs[:progress] || 0
|
247
|
+
@errors = attrs[:errors] || []
|
248
|
+
@data = attrs[:data]
|
249
|
+
@attempt = attrs[:attempt] || 0
|
250
|
+
@job_args = attrs[:job_args] || {}
|
251
|
+
@job_name = attrs[:job_name]
|
252
|
+
@provider_job_id = attrs[:provider_job_id]
|
253
|
+
|
254
|
+
return unless attrs[:persist]
|
255
|
+
|
256
|
+
transaction do
|
257
|
+
set(
|
258
|
+
id: id,
|
259
|
+
progress: progress,
|
260
|
+
errors: errors,
|
261
|
+
attempt: attempt
|
262
|
+
)
|
263
|
+
move_to_state!(state)
|
262
264
|
end
|
263
265
|
end
|
264
266
|
|
@@ -310,6 +312,7 @@ module Jobba
|
|
310
312
|
|
311
313
|
def set_state_in_redis(hash)
|
312
314
|
return unless hash[:state]
|
315
|
+
|
313
316
|
redis.srem(state.name, id) unless state.nil? # leave old state if set
|
314
317
|
redis.sadd(hash[:state].name, id) # enter new state
|
315
318
|
end
|
@@ -324,11 +327,11 @@ module Jobba
|
|
324
327
|
end
|
325
328
|
|
326
329
|
def set_hash_locally(hash)
|
327
|
-
hash.each{ |key, value|
|
330
|
+
hash.each { |key, value| send("#{key}=", value) }
|
328
331
|
end
|
329
332
|
|
330
333
|
def delete_in_redis!
|
331
|
-
|
334
|
+
transaction do
|
332
335
|
redis.del(job_key)
|
333
336
|
|
334
337
|
State::ALL.each do |state|
|
@@ -353,31 +356,32 @@ module Jobba
|
|
353
356
|
end
|
354
357
|
|
355
358
|
def delete_self_from_job_args_set!
|
356
|
-
|
359
|
+
job_args.values.each do |arg|
|
357
360
|
redis.srem(job_arg_key(arg), id)
|
358
361
|
end
|
359
362
|
end
|
360
363
|
|
361
364
|
def add_self_to_job_args_set!
|
362
|
-
|
365
|
+
job_args.values.each do |arg|
|
363
366
|
redis.sadd(job_arg_key(arg), id)
|
364
367
|
end
|
365
368
|
end
|
366
369
|
|
367
370
|
def clear_attrs
|
368
|
-
self.class.local_attrs.each{|aa| send("#{aa}=",nil)}
|
371
|
+
self.class.local_attrs.each { |aa| send("#{aa}=", nil) }
|
369
372
|
end
|
370
373
|
|
371
374
|
def job_name_key
|
372
375
|
"job_name:#{job_name}"
|
373
376
|
end
|
374
377
|
|
375
|
-
def job_key(attempt=nil)
|
378
|
+
def job_key(attempt = nil)
|
376
379
|
self.class.job_key(id, attempt)
|
377
380
|
end
|
378
381
|
|
379
|
-
def self.job_key(id, attempt=nil)
|
380
|
-
raise ArgumentError,
|
382
|
+
def self.job_key(id, attempt = nil)
|
383
|
+
raise ArgumentError, '`id` cannot be nil', caller if id.nil?
|
384
|
+
|
381
385
|
attempt.nil? ? "id:#{id}" : "id:#{id}:#{attempt}"
|
382
386
|
end
|
383
387
|
|
@@ -390,20 +394,21 @@ module Jobba
|
|
390
394
|
end
|
391
395
|
|
392
396
|
def job_errors_key(id)
|
393
|
-
raise ArgumentError,
|
397
|
+
raise ArgumentError, '`id` cannot be nil', caller if id.nil?
|
398
|
+
|
394
399
|
"#{id}:errors"
|
395
400
|
end
|
396
401
|
|
397
402
|
def compute_fractional_progress(at, out_of)
|
398
403
|
if at.nil?
|
399
|
-
raise ArgumentError,
|
404
|
+
raise ArgumentError, 'Must specify at least `at` argument to `progress` call', caller
|
400
405
|
elsif at < 0
|
401
406
|
raise ArgumentError, "progress cannot be negative (at=#{at})", caller
|
402
407
|
elsif out_of && out_of < at
|
403
|
-
raise ArgumentError,
|
408
|
+
raise ArgumentError, '`out_of` must be greater than `at` in `progress` calls', caller
|
404
409
|
elsif out_of.nil? && (at < 0 || at > 1)
|
405
410
|
raise ArgumentError,
|
406
|
-
|
411
|
+
'If `out_of` not specified, `at` must be in the range [0.0, 1.0]',
|
407
412
|
caller
|
408
413
|
end
|
409
414
|
|
@@ -413,6 +418,5 @@ module Jobba
|
|
413
418
|
def now
|
414
419
|
[time = Jobba::Time.now, Utils.time_to_usec_int(time)]
|
415
420
|
end
|
416
|
-
|
417
421
|
end
|
418
422
|
end
|
data/lib/jobba/statuses.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Jobba::Statuses
|
2
|
-
|
3
2
|
include Jobba::Common
|
4
3
|
extend Forwardable
|
5
4
|
|
@@ -26,7 +25,7 @@ class Jobba::Statuses
|
|
26
25
|
if any?(&:incomplete?)
|
27
26
|
raise(Jobba::NotCompletedError,
|
28
27
|
"This status cannot be deleted because it isn't complete. Use " \
|
29
|
-
|
28
|
+
'`delete_all!` if you want to delete anyway.')
|
30
29
|
end
|
31
30
|
|
32
31
|
delete_all!
|
@@ -38,7 +37,7 @@ class Jobba::Statuses
|
|
38
37
|
# preload prior attempts because loading them is not `multi`-friendly
|
39
38
|
@cache.each { |cache| cache.prior_attempts.each(&:prior_attempts) }
|
40
39
|
|
41
|
-
|
40
|
+
transaction do
|
42
41
|
@cache.each(&:delete!)
|
43
42
|
end
|
44
43
|
@cache = []
|
@@ -47,15 +46,15 @@ class Jobba::Statuses
|
|
47
46
|
|
48
47
|
def request_kill_all!
|
49
48
|
load
|
50
|
-
|
49
|
+
transaction do
|
51
50
|
@cache.each(&:request_kill!)
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
55
54
|
def multi(&block)
|
56
55
|
load
|
57
|
-
|
58
|
-
@cache.each{|status| block.call(status, redis)}
|
56
|
+
transaction do
|
57
|
+
@cache.each { |status| block.call(status, redis) }
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
@@ -66,11 +65,11 @@ class Jobba::Statuses
|
|
66
65
|
end
|
67
66
|
|
68
67
|
def get_all!
|
69
|
-
id_keys = @ids.collect{|id| "id:#{id}"}
|
68
|
+
id_keys = @ids.collect { |id| "id:#{id}" }
|
70
69
|
|
71
|
-
raw_statuses = redis.pipelined do
|
70
|
+
raw_statuses = redis.pipelined do |pipe|
|
72
71
|
id_keys.each do |key|
|
73
|
-
|
72
|
+
pipe.hgetall(key)
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
@@ -83,6 +82,7 @@ class Jobba::Statuses
|
|
83
82
|
|
84
83
|
def modify!(method, &block)
|
85
84
|
raise Jobba::NotImplemented unless block_given?
|
85
|
+
|
86
86
|
load
|
87
87
|
if @cache.send(method, &block).nil?
|
88
88
|
nil
|
@@ -96,5 +96,4 @@ class Jobba::Statuses
|
|
96
96
|
@ids = [ids].flatten.compact
|
97
97
|
@cache = nil
|
98
98
|
end
|
99
|
-
|
100
99
|
end
|
data/lib/jobba/version.rb
CHANGED
data/lib/jobba.rb
CHANGED
@@ -2,23 +2,22 @@ require 'delegate'
|
|
2
2
|
require 'forwardable'
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
5
|
+
require 'redis'
|
6
|
+
require 'redis-namespace'
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
8
|
+
require 'jobba/version'
|
9
|
+
require 'jobba/exceptions'
|
10
|
+
require 'jobba/time'
|
11
|
+
require 'jobba/utils'
|
12
|
+
require 'jobba/configuration'
|
13
|
+
require 'jobba/common'
|
14
|
+
require 'jobba/redis_with_expiration'
|
15
|
+
require 'jobba/state'
|
16
|
+
require 'jobba/status'
|
17
|
+
require 'jobba/statuses'
|
18
|
+
require 'jobba/query'
|
19
19
|
|
20
20
|
module Jobba
|
21
|
-
|
22
21
|
class << self
|
23
22
|
extend Forwardable
|
24
23
|
|
@@ -34,6 +33,8 @@ module Jobba
|
|
34
33
|
end
|
35
34
|
|
36
35
|
def self.redis
|
36
|
+
return @transaction if @transaction
|
37
|
+
|
37
38
|
@redis ||= Jobba::RedisWithExpiration.new(
|
38
39
|
Redis::Namespace.new(
|
39
40
|
configuration.namespace,
|
@@ -42,7 +43,24 @@ module Jobba
|
|
42
43
|
)
|
43
44
|
end
|
44
45
|
|
45
|
-
def self.
|
46
|
+
def self.transaction(&block)
|
47
|
+
return @transaction unless block_given?
|
48
|
+
|
49
|
+
if @transaction
|
50
|
+
block.call(@transaction)
|
51
|
+
else
|
52
|
+
redis.multi do |trn|
|
53
|
+
@transaction = trn
|
54
|
+
begin
|
55
|
+
block.call(@transaction)
|
56
|
+
ensure
|
57
|
+
@transaction = nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.cleanup(seconds_ago: 60 * 60 * 24 * 30 * 12, batch_size: 1000)
|
46
64
|
start_time = Jobba::Time.now
|
47
65
|
delete_before = start_time - seconds_ago
|
48
66
|
|
@@ -62,5 +80,4 @@ module Jobba
|
|
62
80
|
def self.clear_all_jobba_data!
|
63
81
|
cleanup(seconds_ago: 0)
|
64
82
|
end
|
65
|
-
|
66
83
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jobba
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JP Slavinsky
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: oj
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,19 +25,19 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: redis
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '4.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '4.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: redis-namespace
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: byebug
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: fakeredis
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
160
|
- !ruby/object:Gem::Version
|
161
161
|
version: '0'
|
162
162
|
requirements: []
|
163
|
-
rubygems_version: 3.
|
163
|
+
rubygems_version: 3.2.33
|
164
164
|
signing_key:
|
165
165
|
specification_version: 4
|
166
166
|
summary: Redis-based background job status tracking.
|