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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 489a463b81e0d1dc9d7f8c79b1aacd25ab66358cea92a2692e4428e0f7b30a54
4
- data.tar.gz: c8eb29ef8b368390b1f78eec40a04aaa06cc4dee3b45453355d9109eace62fa7
3
+ metadata.gz: 1fd0ebb186e9eca18861196616b9d2e6518d1193e5672ae68d783762e3a1f6f7
4
+ data.tar.gz: af77889b9e09fd57d965fe8b8b8c619b13d6b21ce249d7c4d5677f9f537d41ab
5
5
  SHA512:
6
- metadata.gz: 16abf20ee8428d89b11c1e76315e957a357bf4f4381b4c072efdfd90365d5863a558f2a92f0b051fda32bde52f58d012b17000a5602050be77e9202a609f7cd3
7
- data.tar.gz: 6b63cffc85fa57a36b454913a016b6b745e7975c3741868644735505315068086f01e5dd07cb1613304dafce896a4e537f2c169c55a4926ea0d833b4949efabd
6
+ metadata.gz: 0c1ef1efbc0496d339e79d188a56718b9db416b28e62ac6e247e91ab0c43ce0313e02a7dee103b8cfe1dc034005567a55fd8db1811487c331d2396bc5de555b0
7
+ data.tar.gz: 668c4722c4bd2505d84cad9860dec70a028acee23d980ce99d67d0969d4e9164ae5d9dca08ef15ec465c226046242429c95e18c3cd94a6e60efabacd5323a2d8
@@ -12,12 +12,12 @@ on:
12
12
  jobs:
13
13
  tests:
14
14
  timeout-minutes: 30
15
- runs-on: ubuntu-18.04
15
+ runs-on: ubuntu-22.04
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
19
  os: [ubuntu]
20
- ruby: [ '2.5', '2.6', '2.7' ]
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@v2
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
- # coding: utf-8
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 = "jobba"
6
+ spec.name = 'jobba'
8
7
  spec.version = Jobba::VERSION
9
- spec.authors = ["JP Slavinsky"]
10
- spec.email = ["jps@kindlinglabs.com"]
8
+ spec.authors = ['JP Slavinsky']
9
+ spec.email = ['jps@kindlinglabs.com']
11
10
 
12
- spec.summary = %q{Redis-based background job status tracking.}
13
- spec.description = %q{Redis-based background job status tracking.}
14
- spec.homepage = "https://github.com/openstax/jobba"
15
- spec.license = "MIT"
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 = "exe"
17
+ spec.bindir = 'exe'
19
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
21
20
 
22
- spec.add_runtime_dependency "redis"
23
- spec.add_runtime_dependency "oj"
24
- spec.add_runtime_dependency "redis-namespace"
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 "rake"
27
- spec.add_development_dependency "rspec"
28
- spec.add_development_dependency "byebug"
29
- spec.add_development_dependency "fakeredis"
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(clause)
76
- raise "AbstractMethod"
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(result_set)
83
- raise "AbstractMethod"
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(redis_output)
88
- raise "AbstractMethod"
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 = redis.multi do
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
- redis.zinterstore(working_set, [working_set, clause_set], weights: [0, 0])
159
- redis.del(clause_set)
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
- redis.del(working_set)
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(id state progress errors data kill_requested_at
44
- job_name job_args provider_job_id attempt prior_attempts) +
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 <<-eoruby
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
- eoruby
66
+ EORUBY
68
67
  end
69
68
 
70
69
  State::ENTERABLE.each do |state|
71
70
  define_method("#{state.name}!") do
72
- redis.multi do
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
- !self.started_at.nil?
98
+ !started_at.nil?
100
99
  end
101
100
 
102
101
  def request_kill!
103
102
  time, usec_int = now
104
- if redis.hsetnx(job_key, :kill_requested_at, usec_int)
105
- @kill_requested_at = time
106
- end
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, "`job_name` must not be blank", caller \
118
+ raise ArgumentError, '`job_name` must not be blank', caller \
120
119
  if job_name.nil? || job_name.empty?
121
120
 
122
- redis.multi do
123
- redis.srem(job_name_key, id)
121
+ transaction do |trn|
122
+ trn.srem(job_name_key, id)
124
123
  set(job_name: job_name)
125
- redis.sadd(job_name_key, id)
124
+ trn.sadd(job_name_key, id)
126
125
  end
127
126
  end
128
127
 
129
- def set_job_args(args_hash={})
130
- raise ArgumentError,
131
- "All values in the hash passed to `set_job_args` must be strings",
132
- caller if args_hash.values.any?{|val| !val.is_a?(String)}
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
- redis.multi do
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, "`provider_job_id` must not be blank", caller \
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
- redis.multi do
148
- redis.srem(provider_job_id_key, id)
148
+ transaction do |trn|
149
+ trn.srem(provider_job_id_key, id)
149
150
  set(provider_job_id: provider_job_id)
150
- redis.sadd(provider_job_id_key, id)
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, "The argument to `add_error` cannot be nil", caller if error.nil?
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
- raise(NotCompletedError, "This status cannot be deleted because it " \
177
- "isn't complete. Use `delete!` if you want to " \
178
- "delete anyway.")
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
- if @json_encoded_attrs.nil? || @json_encoded_attrs.empty?
240
-
241
- @id = attrs[:id] || SecureRandom.uuid
242
- @state = attrs[:state] || State::UNKNOWN
243
- @progress = attrs[:progress] || 0
244
- @errors = attrs[:errors] || []
245
- @data = attrs[:data]
246
- @attempt = attrs[:attempt] || 0
247
- @job_args = attrs[:job_args] || {}
248
- @job_name = attrs[:job_name]
249
- @provider_job_id = attrs[:provider_job_id]
250
-
251
- if attrs[:persist]
252
- redis.multi do
253
- set(
254
- id: id,
255
- progress: progress,
256
- errors: errors,
257
- attempt: attempt
258
- )
259
- move_to_state!(state)
260
- end
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| self.send("#{key}=", value) }
330
+ hash.each { |key, value| send("#{key}=", value) }
328
331
  end
329
332
 
330
333
  def delete_in_redis!
331
- redis.multi do
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
- self.job_args.values.each do |arg|
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
- self.job_args.values.each do |arg|
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, "`id` cannot be nil", caller if id.nil?
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, "`id` cannot be nil", caller if id.nil?
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, "Must specify at least `at` argument to `progress` call", caller
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, "`out_of` must be greater than `at` in `progress` calls", caller
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
- "If `out_of` not specified, `at` must be in the range [0.0, 1.0]",
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
@@ -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
- "`delete_all!` if you want to delete anyway.")
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
- redis.multi do
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
- redis.multi do
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
- redis.multi do
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
- redis.hgetall(key)
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
@@ -1,3 +1,3 @@
1
1
  module Jobba
2
- VERSION = "1.8.1"
2
+ VERSION = '2.0.0'
3
3
  end
data/lib/jobba.rb CHANGED
@@ -2,23 +2,22 @@ require 'delegate'
2
2
  require 'forwardable'
3
3
  require 'securerandom'
4
4
 
5
- require "redis"
6
- require "redis-namespace"
5
+ require 'redis'
6
+ require 'redis-namespace'
7
7
 
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"
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.cleanup(seconds_ago: 60*60*24*30*12, batch_size: 1000)
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: 1.8.1
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: 2021-10-21 00:00:00.000000000 Z
11
+ date: 2023-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: redis
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: oj
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: rake
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: rspec
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: byebug
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: fakeredis
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.1.4
163
+ rubygems_version: 3.2.33
164
164
  signing_key:
165
165
  specification_version: 4
166
166
  summary: Redis-based background job status tracking.