jobba 1.8.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|