dalliance 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33f7433a3391650bd85c64aa0168d2ba9c47a58623fb939241f5d379f9fd621e
4
- data.tar.gz: f0cd58c87d0c512592ca19ea3f25d572569302a1e2c2fb4c8a0864ac2827a9d5
3
+ metadata.gz: bfda33ea2cc9d97c6896fbab7cfb6d3c644ce56c64f22632c5e744544770a853
4
+ data.tar.gz: cdd5a93b644a426edc9a4007ef65c373aebe6fe9aac7b30f3096a47fdfaa11e6
5
5
  SHA512:
6
- metadata.gz: 6882e52916979a54c75a589ead81bb4a20b2639129ae18751afc11c45ccd6e1ddd2c2eee0ecb43ed9901c0ebd9d4e194621321c7d8e2474ec69c804d4e6c7884
7
- data.tar.gz: c1e5741fdcfcb3914d8b729476a7e12c64305125abb94a10687dd79693ef5499d0c61467b466e387dc3a60fd62e56354e97e17ce1f7f38d63cdc94ba76d69aa0
6
+ metadata.gz: 674870bb0d8db5f0baf0cd27f7475cda00de7fd5a8b3d5b37c96ec6c008f127377b6e4ed8519d24ef6792d8ec74a4660ca85310e89594cfbb477085710c6a2d7
7
+ data.tar.gz: 4227f25b65186249d137ccd242df99adf6bd70a4b3993799c79a60bbb57d7bca799e7236de219da44cb8539e3bc73ffbbea3fc197eaf37caeb136341bf98844d
@@ -0,0 +1,107 @@
1
+ version: 2.1
2
+
3
+ defaults: &defaults
4
+ working_directory: ~/app
5
+ docker:
6
+ - image: circleci/ruby:2.6.5
7
+ - image: redis
8
+ # - image: circleci/mysql:5.7
9
+ # environment:
10
+ # MYSQL_USER: root
11
+ # MYSQL_PASSWORD: ''
12
+
13
+ jobs:
14
+ build:
15
+ <<: *defaults
16
+ parallelism: 1
17
+ steps:
18
+ - checkout
19
+
20
+
21
+ - restore_cache:
22
+ keys:
23
+ - v2-bundle-{{ checksum "Gemfile.lock" }}
24
+ - run:
25
+ name: Bundle install
26
+ command: bundle check || bundle install --retry=3 --path vendor/bundle
27
+ - save_cache:
28
+ key: v2-bundle-{{ checksum "Gemfile.lock" }}
29
+ paths:
30
+ - vendor/bundle
31
+ - persist_to_workspace:
32
+ root: ~/
33
+ paths:
34
+ - app
35
+
36
+ test:
37
+ <<: *defaults
38
+ parallelism: 1
39
+ steps:
40
+ - attach_workspace:
41
+ at: ~/
42
+
43
+ - run: bundle --path vendor/bundle
44
+
45
+ # - run:
46
+ # name: Wait for DB
47
+ # command: dockerize -wait tcp://localhost:3306 -timeout 1m
48
+
49
+ - run:
50
+ name: Run RSpec tests
51
+ command: |
52
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
53
+ echo $TEST_FILES
54
+ bundle exec rspec --profile 10 \
55
+ --format RspecJunitFormatter \
56
+ --out test_results/rspec.xml \
57
+ --format progress \
58
+ $TEST_FILES
59
+ - store_test_results:
60
+ path: test_results
61
+ - store_artifacts:
62
+ path: test_results
63
+
64
+ bundler_audit:
65
+ <<: *defaults
66
+ parallelism: 1
67
+ steps:
68
+ - attach_workspace:
69
+ at: ~/
70
+ - run: bundle --path vendor/bundle
71
+ - run:
72
+ name: Run bundler-audit
73
+ command: |
74
+ if [[ "${CIRCLE_NODE_INDEX}" == 0 ]]
75
+ then
76
+ bundle exec bundle-audit update && bundle exec bundle-audit check
77
+ fi
78
+
79
+ rubocop:
80
+ <<: *defaults
81
+ parallelism: 1
82
+ steps:
83
+ - attach_workspace:
84
+ at: ~/
85
+ - run: bundle --path vendor/bundle
86
+ - run:
87
+ name: Run rubocop
88
+ command: |
89
+ if [[ "${CIRCLE_NODE_INDEX}" == 0 ]]
90
+ then
91
+ bundle exec rubocop -D -l
92
+ fi
93
+
94
+ workflows:
95
+ version: 2
96
+ continuous_integration:
97
+ jobs:
98
+ - build
99
+ - test:
100
+ requires:
101
+ - build
102
+ - bundler_audit:
103
+ requires:
104
+ - build
105
+ - rubocop:
106
+ requires:
107
+ - build
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in dalliance.gemspec
4
4
  gemspec
@@ -19,7 +19,19 @@ In your model:
19
19
  process_method is the name of the method to invoke for background processing
20
20
  to kick it off just call dalliance_background_process
21
21
 
22
- Handle your migrations:
22
+ Models can also be re-processed to allow front-end users to reprocess without
23
+ needing to loop in PMs or developers:
24
+
25
+ class Model < ActiveRecord::Base
26
+ dalliance :process_method,
27
+ reprocess_method: :reprocessing_method
28
+ end
29
+
30
+ Keep in mind that a record that has not already been completely processed (eg in
31
+ a state of 'pending' or 'processing') cannot be reprocessed. Attempting to
32
+ reprocess the record will raise an error.
33
+
34
+ == Handle your migrations:
23
35
 
24
36
  rails g dalliance:progress_meter
25
37
 
@@ -11,8 +11,6 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{ Wrapper for an ActiveRecord model with a single ascynhronous method }
12
12
  s.description = %q{ Background processing for ActiveRecord using a 'delayable' worker and a state_machine }
13
13
 
14
- s.rubyforge_project = "dalliance"
15
-
16
14
  s.files = `git ls-files`.split("\n")
17
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -26,6 +24,8 @@ Gem::Specification.new do |s|
26
24
  s.add_development_dependency('delayed_job', '>= 3.0.0')
27
25
  s.add_development_dependency('delayed_job_active_record')
28
26
  s.add_development_dependency('sqlite3')
29
-
30
27
  s.add_development_dependency('resque')
28
+ s.add_development_dependency('bundler-audit')
29
+ s.add_development_dependency('rubocop', '~> 0.78')
30
+ s.add_development_dependency('rspec_junit_formatter')
31
31
  end
@@ -6,7 +6,7 @@ PATH
6
6
  state_machine
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
11
  actionmailer (4.2.9)
12
12
  actionpack (= 4.2.9)
@@ -6,7 +6,7 @@ PATH
6
6
  state_machine
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
11
  actioncable (5.0.0)
12
12
  actionpack (= 5.0.0)
@@ -6,7 +6,7 @@ PATH
6
6
  state_machine
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
11
  actioncable (5.1.7)
12
12
  actionpack (= 5.1.7)
@@ -6,7 +6,7 @@ PATH
6
6
  state_machine
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
11
  actioncable (5.2.3)
12
12
  actionpack (= 5.2.3)
@@ -118,6 +118,10 @@ module Dalliance
118
118
  event :finish_dalliance do
119
119
  transition :processing => :completed
120
120
  end
121
+
122
+ event :reprocess_dalliance do
123
+ transition [:validation_error, :processing_error, :completed] => :pending
124
+ end
121
125
  end
122
126
  #END state_machine(s)
123
127
 
@@ -175,7 +179,9 @@ module Dalliance
175
179
  else
176
180
  self.class.where(id: self.id).update_all(dalliance_status: dalliance_status, dalliance_error_hash: dalliance_error_hash.to_yaml )
177
181
  end
182
+ # rubocop:disable Lint/SuppressedException
178
183
  rescue
184
+ # rubocop:enable Lint/SuppressedException
179
185
  end
180
186
  end
181
187
  end
@@ -213,17 +219,40 @@ module Dalliance
213
219
  end
214
220
  end
215
221
 
216
- #Force backgound_processing w/ true
217
- def dalliance_background_process(backgound_processing = nil)
218
- if backgound_processing || (backgound_processing.nil? && self.class.dalliance_options[:background_processing])
219
- self.class.dalliance_options[:worker_class].enqueue(self, processing_queue)
222
+ #Force background_processing w/ true
223
+ def dalliance_background_process(background_processing = nil)
224
+ if background_processing || (background_processing.nil? && self.class.dalliance_options[:background_processing])
225
+ self.class.dalliance_options[:worker_class].enqueue(self, processing_queue, :dalliance_process)
220
226
  else
221
227
  dalliance_process(false)
222
228
  end
223
229
  end
224
230
 
225
- #backgound_processing == false will re-raise any exceptions
226
- def dalliance_process(backgound_processing = false)
231
+ def dalliance_process(background_processing = false)
232
+ do_dalliance_process(
233
+ perform_method: self.class.dalliance_options[:dalliance_method],
234
+ background_processing: background_processing
235
+ )
236
+ end
237
+
238
+ def dalliance_background_reprocess(background_processing = nil)
239
+ if background_processing || (background_processing.nil? && self.class.dalliance_options[:background_processing])
240
+ self.class.dalliance_options[:worker_class].enqueue(self, processing_queue, :dalliance_reprocess)
241
+ else
242
+ dalliance_reprocess(false)
243
+ end
244
+ end
245
+
246
+ def dalliance_reprocess(background_processing = false)
247
+ reprocess_dalliance!
248
+
249
+ do_dalliance_process(
250
+ perform_method: self.class.dalliance_options[:reprocess_method],
251
+ background_processing: background_processing
252
+ )
253
+ end
254
+
255
+ def do_dalliance_process(perform_method:, background_processing: false)
227
256
  start_time = Time.now
228
257
 
229
258
  begin
@@ -233,7 +262,7 @@ module Dalliance
233
262
  build_dalliance_progress_meter(:total_count => calculate_dalliance_progress_meter_total_count).save!
234
263
  end
235
264
 
236
- self.send(self.class.dalliance_options[:dalliance_method])
265
+ self.send(perform_method)
237
266
 
238
267
  finish_dalliance! unless validation_error?
239
268
  rescue StandardError => e
@@ -255,14 +284,16 @@ module Dalliance
255
284
  else
256
285
  self.class.where(id: self.id).update_all(dalliance_status: dalliance_status, dalliance_error_hash: dalliance_error_hash.to_yaml )
257
286
  end
287
+ # rubocop:disable Lint/SuppressedException
258
288
  rescue
289
+ # rubocop:enable Lint/SuppressedException
259
290
  end
260
291
  end
261
292
 
262
293
  error_notifier.call(e)
263
294
 
264
- #Don't raise the error if we're backgound_processing...
265
- raise e unless backgound_processing && self.class.dalliance_options[:worker_class].rescue_error?
295
+ # Don't raise the error if we're background processing...
296
+ raise e unless background_processing && self.class.dalliance_options[:worker_class].rescue_error?
266
297
  ensure
267
298
  if self.class.dalliance_options[:dalliance_progress_meter] && dalliance_progress_meter
268
299
  #Works with optimistic locking...
@@ -274,8 +305,11 @@ module Dalliance
274
305
 
275
306
  dalliance_log("[dalliance] #{self.class.name}(#{id}) - #{dalliance_status} #{duration.to_i}")
276
307
 
277
- if self.class.dalliance_options[:duration_column]
278
- self.class.where(id: self.id).update_all(self.class.dalliance_options[:duration_column] => duration.to_i)
308
+ duration_column = self.class.dalliance_options[:duration_column]
309
+ if duration_column.present?
310
+ current_duration = self.send(duration_column) || 0
311
+ self.class.where(id: self.id)
312
+ .update_all(duration_column => current_duration + duration.to_f)
279
313
  end
280
314
  end
281
315
  end
@@ -313,15 +347,28 @@ module Dalliance
313
347
  end
314
348
 
315
349
  module ClassMethods
316
- def dalliance(*args)
317
- options = args.last.is_a?(Hash) ? Dalliance.options.merge(args.pop) : Dalliance.options
318
-
319
- case args.length
320
- when 1
321
- options[:dalliance_method] = args[0]
322
- else
323
- raise ArgumentError, "Incorrect number of Arguements provided"
324
- end
350
+ # Enables dalliance processing for this class.
351
+ #
352
+ # @param [Symbol|String] dalliance_method
353
+ # the name of the method to call when processing the model in dalliance
354
+ # @param [Hash] options
355
+ # an optional hash of options for dalliance processing
356
+ # @option options [Symbol] :reprocess_method
357
+ # the name of the method to use to reprocess the model in dalliance
358
+ # @option options [Boolean] :dalliance_process_meter
359
+ # whether or not to display a progress meter
360
+ # @option options [String] :queue
361
+ # the name of the worker queue to use. Default 'dalliance'
362
+ # @option options [String] :duration_column
363
+ # the name of the table column that stores the dalliance processing time. Default 'dalliance_duration'
364
+ # @option options [Object] :logger
365
+ # the logger object to use. Can be nil
366
+ # @option options [Proc] :error_notifier
367
+ # A proc that accepts an error object. Default is a NOP
368
+ def dalliance(dalliance_method, options = {})
369
+ opts = Dalliance.options.merge(options)
370
+
371
+ opts[:dalliance_method] = dalliance_method
325
372
 
326
373
  if dalliance_options.nil?
327
374
  self.dalliance_options = {}
@@ -329,7 +376,7 @@ module Dalliance
329
376
  self.dalliance_options = self.dalliance_options.dup
330
377
  end
331
378
 
332
- self.dalliance_options.merge!(options)
379
+ self.dalliance_options.merge!(opts)
333
380
 
334
381
  include Dalliance
335
382
  end
@@ -7,7 +7,7 @@ module Dalliance
7
7
  ActiveSupport.on_load :active_record do
8
8
  include Dalliance::Glue
9
9
 
10
- ActiveRecord::ConnectionAdapters::TableDefinition.send(:include, Dalliance::Schema)
10
+ ActiveRecord::ConnectionAdapters::TableDefinition.include Dalliance::Schema
11
11
  end
12
12
  end
13
13
  end
@@ -46,20 +46,20 @@ module Dalliance
46
46
  #TODO: This is just a stopgap until I fix increment! to be thread-safe
47
47
  def progress
48
48
  begin
49
- _progress = (current_count.to_f / total_count.to_f * 100).to_i
49
+ current_progress = (current_count.to_f / total_count.to_f * 100).to_i
50
50
 
51
51
  #Handle an incorrect total_count...
52
- _progress = 100 if _progress > 100
52
+ current_progress = 100 if current_progress > 100
53
53
  rescue
54
54
  #what, are you diving by zero?
55
- _progress = 0
55
+ current_progress = 0
56
56
  end
57
57
 
58
- _progress
58
+ current_progress
59
59
  end
60
60
 
61
61
  def increment!
62
62
  Dalliance::ProgressMeter.increment_counter(:current_count, self.id)
63
63
  end
64
64
  end
65
- end
65
+ end
@@ -1,7 +1,7 @@
1
1
  module Dalliance
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 6
4
+ MINOR = 7
5
5
  TINY = 0
6
6
  PRE = nil
7
7
 
@@ -4,12 +4,17 @@ module Dalliance
4
4
  class DelayedJob < ::ActiveJob::Base
5
5
  queue_as :dalliance
6
6
 
7
- def self.enqueue(instance, queue = 'dalliance')
8
- Dalliance::Workers::DelayedJob.set(queue: queue).perform_later(instance.class.name, instance.id)
7
+ def self.enqueue(instance, queue = 'dalliance', perform_method)
8
+ Dalliance::Workers::DelayedJob
9
+ .set(queue: queue)
10
+ .perform_later(instance.class.name, instance.id, perform_method.to_s)
9
11
  end
10
12
 
11
- def perform(instance_klass, instance_id)
12
- instance_klass.constantize.find(instance_id).dalliance_process(true)
13
+ def perform(instance_klass, instance_id, perform_method)
14
+ instance_klass
15
+ .constantize
16
+ .find(instance_id)
17
+ .send(perform_method, true)
13
18
  end
14
19
 
15
20
  #Delayed job automatically retries, so rescue the error
@@ -18,13 +23,19 @@ module Dalliance
18
23
  end
19
24
  end
20
25
  else
21
- class DelayedJob < Struct.new(:instance_klass, :instance_id)
22
- def self.enqueue(instance, queue = 'dalliance')
23
- ::Delayed::Job.enqueue(self.new(instance.class.name, instance.id), :queue => queue)
26
+ class DelayedJob < Struct.new(:instance_klass, :instance_id, :perform_method)
27
+ def self.enqueue(instance, queue = 'dalliance', perform_method)
28
+ ::Delayed::Job.enqueue(
29
+ self.new(instance.class.name, instance.id, perform_method),
30
+ :queue => queue
31
+ )
24
32
  end
25
33
 
26
34
  def perform
27
- instance_klass.constantize.find(instance_id).dalliance_process(true)
35
+ instance_klass
36
+ .constantize
37
+ .find(instance_id)
38
+ .send(perform_method, true)
28
39
  end
29
40
 
30
41
  #Delayed job automatically retries, so rescue the error
@@ -4,12 +4,17 @@ module Dalliance
4
4
  class Resque < ::ActiveJob::Base
5
5
  queue_as :dalliance
6
6
 
7
- def self.enqueue(instance, queue = 'dalliance')
8
- Dalliance::Workers::Resque.set(queue: queue).perform_later(instance.class.name, instance.id)
7
+ def self.enqueue(instance, queue = 'dalliance', perform_method)
8
+ Dalliance::Workers::Resque
9
+ .set(queue: queue)
10
+ .perform_later(instance.class.name, instance.id, perform_method.to_s)
9
11
  end
10
12
 
11
- def perform(instance_klass, instance_id)
12
- instance_klass.constantize.find(instance_id).dalliance_process(true)
13
+ def perform(instance_klass, instance_id, perform_method)
14
+ instance_klass
15
+ .constantize
16
+ .find(instance_id)
17
+ .send(perform_method, true)
13
18
  end
14
19
 
15
20
  #Resque fails, so don't rescue the error
@@ -19,12 +24,15 @@ module Dalliance
19
24
  end
20
25
  else
21
26
  class Resque
22
- def self.enqueue(instance, queue = 'dalliance')
23
- ::Resque.enqueue_to(queue, self, instance.class.name, instance.id)
27
+ def self.enqueue(instance, queue = 'dalliance', perform_method)
28
+ ::Resque.enqueue_to(queue, self, instance.class.name, instance.id, perform_method.to_s)
24
29
  end
25
30
 
26
- def self.perform(instance_klass, instance_id)
27
- instance_klass.constantize.find(instance_id).dalliance_process(true)
31
+ def self.perform(instance_klass, instance_id, perform_method)
32
+ instance_klass
33
+ .constantize
34
+ .find(instance_id)
35
+ .send(perform_method, true)
28
36
  end
29
37
 
30
38
  #Resque fails, so don't rescue the error
@@ -77,6 +77,37 @@ RSpec.describe DallianceModel do
77
77
  expect(subject.dalliance_duration).not_to eq(nil)
78
78
  end
79
79
 
80
+ context 'reprocess' do
81
+ before(:all) do
82
+ DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::DelayedJob
83
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
84
+ end
85
+
86
+ before do
87
+ subject.dalliance_process
88
+ subject.reload
89
+ end
90
+
91
+ it 'successfully runs the dalliance_reprocess method' do
92
+ subject.dalliance_background_reprocess
93
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
94
+ subject.reload
95
+
96
+ expect(subject).to be_successful
97
+ expect(Delayed::Job.count).to eq(0)
98
+ expect(subject.reprocessed_count).to eq(1)
99
+ end
100
+
101
+ it 'increases the total processing time counter' do
102
+ original_duration = subject.dalliance_duration
103
+ subject.dalliance_background_reprocess
104
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
105
+ subject.reload
106
+
107
+ expect(subject.dalliance_duration).to be_between(original_duration, Float::INFINITY)
108
+ end
109
+ end
110
+
80
111
  context "another_queue" do
81
112
  let(:queue) { 'dalliance_2'}
82
113
 
@@ -114,6 +114,44 @@ RSpec.describe DallianceModel do
114
114
  end
115
115
  end
116
116
 
117
+ context 'reprocess' do
118
+ before :all do
119
+ DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::Resque
120
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
121
+ end
122
+
123
+ before do
124
+ subject.dalliance_process
125
+ subject.reload
126
+ end
127
+
128
+ it 'successfully runs the dalliance_reprocess method' do
129
+ Resque::Stat.clear(:processed)
130
+ Resque::Stat.clear(:failed)
131
+
132
+ subject.dalliance_background_reprocess
133
+ Resque::Worker.new(:dalliance).process
134
+ subject.reload
135
+
136
+ aggregate_failures do
137
+ expect(subject).to be_successful
138
+ expect(Resque.size(:dalliance)).to eq(0)
139
+ expect(Resque::Stat[:processed]).to eq(1)
140
+ expect(Resque::Stat[:failed]).to eq(0)
141
+ expect(subject.reprocessed_count).to eq(1)
142
+ end
143
+ end
144
+
145
+ it 'increases the total processing time counter' do
146
+ original_duration = subject.dalliance_duration
147
+ subject.dalliance_background_reprocess
148
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
149
+ subject.reload
150
+
151
+ expect(subject.dalliance_duration).to be_between(original_duration, Float::INFINITY)
152
+ end
153
+ end
154
+
117
155
  context "raise error" do
118
156
  before(:all) do
119
157
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
@@ -21,7 +21,7 @@ RSpec.describe 'Dalliance' do
21
21
 
22
22
  context "human_attribute_name" do
23
23
  it "should display the correct locale" do
24
- expect(DallianceModel.human_attribute_name(:dalliance_status)).to eq ('Status')
24
+ expect(DallianceModel.human_attribute_name(:dalliance_status)).to eq('Status')
25
25
  end
26
26
  end
27
27
 
@@ -44,7 +44,7 @@ RSpec.describe 'Dalliance' do
44
44
  end
45
45
 
46
46
  context "w/ args" do
47
- let(:queue) { Proc.new{ |a,b,c| 'dalliance_2' } }
47
+ let(:queue) { Proc.new{ |_a,_b,_c| 'dalliance_2' } }
48
48
 
49
49
  specify{ expect(subject.processing_queue).to eq(queue.call) }
50
50
  end
@@ -35,6 +35,60 @@ RSpec.describe DallianceModel do
35
35
  end
36
36
  end
37
37
 
38
+ context 'reprocess' do
39
+ context 'without having already processed' do
40
+ it 'raises an error' do
41
+ expect { subject.dalliance_background_reprocess }
42
+ .to raise_error(
43
+ StateMachine::InvalidTransition,
44
+ /^Cannot transition dalliance_status via :reprocess_dalliance from :pending.*/
45
+ )
46
+ end
47
+ end
48
+
49
+ context 'when the model has already processed' do
50
+ before do
51
+ subject.dalliance_background_process
52
+ subject.reload
53
+ end
54
+
55
+ it 'calls the dalliance_reprocess method' do
56
+ expect { subject.dalliance_background_reprocess }
57
+ .to change(subject, :reprocessed_count)
58
+ .from(0)
59
+ .to(1)
60
+ end
61
+
62
+ it 'can call the dalliance_reprocess method many times in succession' do
63
+ expect { 10.times { subject.dalliance_background_reprocess } }
64
+ .to change(subject, :reprocessed_count)
65
+ .from(0)
66
+ .to(10)
67
+ end
68
+
69
+ it 'sets the dalliance_status to completed' do
70
+ expect { subject.dalliance_background_reprocess }
71
+ .not_to change { subject.reload.dalliance_status }
72
+ .from('completed')
73
+ end
74
+
75
+ it 'sets the dalliance_progress to 100' do
76
+ expect { subject.dalliance_background_reprocess }
77
+ .not_to change { subject.reload.dalliance_progress }
78
+ .from(100)
79
+ end
80
+
81
+ it 'increases the total processing time counter' do
82
+ original_duration = subject.dalliance_duration
83
+ subject.dalliance_background_reprocess
84
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
85
+ subject.reload
86
+
87
+ expect(subject.dalliance_duration).to be_between(original_duration, Float::INFINITY)
88
+ end
89
+ end
90
+ end
91
+
38
92
  context "raise error" do
39
93
  before(:all) do
40
94
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
@@ -4,10 +4,12 @@ require 'bundler/setup'
4
4
  #Automatically included in a rails app...
5
5
  require 'active_support'
6
6
 
7
+ # rubocop:disable Lint/SuppressedException
7
8
  begin
8
9
  require 'active_job'
9
10
  rescue LoadError
10
11
  end
12
+ # rubocop:enable Lint/SuppressedException
11
13
 
12
14
  require 'state_machine'
13
15
  require 'byebug'
@@ -35,9 +35,10 @@ ActiveRecord::Schema.define do
35
35
  create_table :dalliance_models, :force => true do |t|
36
36
  t.text :dalliance_error_hash
37
37
  t.string :dalliance_status, :string, :null => false, :default => 'pending'
38
- t.integer :dalliance_duration
38
+ t.decimal :dalliance_duration
39
39
 
40
40
  t.boolean :successful, :default => false
41
+ t.integer :reprocessed_count, default: 0
41
42
  end
42
43
  end
43
44
 
@@ -47,12 +48,17 @@ class DallianceModel < ActiveRecord::Base
47
48
  include Dalliance::Glue
48
49
 
49
50
  dalliance :dalliance_success_method,
51
+ reprocess_method: :dalliance_reprocess_method,
50
52
  :logger => nil
51
53
 
52
54
  def dalliance_success_method
53
55
  update_attribute(:successful, true)
54
56
  end
55
57
 
58
+ def dalliance_reprocess_method
59
+ update_attribute(:reprocessed_count, self.reprocessed_count + 1)
60
+ end
61
+
56
62
  def dalliance_error_method
57
63
  raise RuntimeError
58
64
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dalliance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Sullivan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-21 00:00:00.000000000 Z
11
+ date: 2020-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -114,6 +114,48 @@ dependencies:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: bundler-audit
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rubocop
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.78'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.78'
145
+ - !ruby/object:Gem::Dependency
146
+ name: rspec_junit_formatter
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
117
159
  description: " Background processing for ActiveRecord using a 'delayable' worker and
118
160
  a state_machine "
119
161
  email:
@@ -122,6 +164,7 @@ executables: []
122
164
  extensions: []
123
165
  extra_rdoc_files: []
124
166
  files:
167
+ - ".circleci/config.yml"
125
168
  - ".gitignore"
126
169
  - ".rspec"
127
170
  - Appraisals
@@ -176,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
219
  - !ruby/object:Gem::Version
177
220
  version: '0'
178
221
  requirements: []
179
- rubyforge_project: dalliance
222
+ rubyforge_project:
180
223
  rubygems_version: 2.7.6
181
224
  signing_key:
182
225
  specification_version: 4