canvas_sync 0.17.0 → 0.17.3.beta3
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/README.md +58 -0
- data/lib/canvas_sync/job_batches/batch.rb +66 -107
- data/lib/canvas_sync/job_batches/callback.rb +27 -31
- data/lib/canvas_sync/job_batches/context_hash.rb +8 -5
- data/lib/canvas_sync/job_batches/hincr_max.lua +5 -0
- data/lib/canvas_sync/job_batches/jobs/managed_batch_job.rb +99 -0
- data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +6 -65
- data/lib/canvas_sync/job_batches/pool.rb +193 -0
- data/lib/canvas_sync/job_batches/redis_model.rb +69 -0
- data/lib/canvas_sync/job_batches/redis_script.rb +163 -0
- data/lib/canvas_sync/job_batches/sidekiq.rb +22 -1
- data/lib/canvas_sync/job_batches/status.rb +0 -5
- data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +4 -2
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/dummy/log/test.log +82629 -0
- data/spec/job_batching/batch_aware_job_spec.rb +1 -0
- data/spec/job_batching/batch_spec.rb +72 -15
- data/spec/job_batching/callback_spec.rb +1 -1
- data/spec/job_batching/flow_spec.rb +5 -11
- data/spec/job_batching/integration/fail_then_succeed.rb +42 -0
- data/spec/job_batching/integration_helper.rb +6 -4
- data/spec/job_batching/sidekiq_spec.rb +1 -0
- data/spec/job_batching/status_spec.rb +1 -17
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54feabc8f9154b633a70a11d15bfeebaf54ab9d9eb24b9a636c27844728ca1a3
|
4
|
+
data.tar.gz: 0c8d2692a83ebb37a518f61d11fb2970b3204f3d68c990c721fa23a7365a91b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50efdad1e463d363463b72fa2fcc5581f877bdeb2c2440d688b10f451321996d95c7acd610d822fcc943d0220ed5520f4963de12341c1adb4238d131c5d8df04
|
7
|
+
data.tar.gz: 51d40bc898a58a0aab65a85d4c1820ca5da72bf22b4c11e0ee631ad2e815dc344dc4824a2ade24e7485ace7ad0d12692d71cc93054afcfc05269ac22a4f7b4c9
|
data/README.md
CHANGED
@@ -246,6 +246,64 @@ A batch can be created using `Sidekiq::Batch` or `CanvasSync::JobBatching::Batch
|
|
246
246
|
|
247
247
|
Also see `canvas_sync/jobs/begin_sync_chain_job`, `canvas_sync/Job_batches/jobs/serial_batch_job`, or `canvas_sync/Job_batches/jobs/concurrent_batch_job` for example usage.
|
248
248
|
|
249
|
+
Example:
|
250
|
+
```ruby
|
251
|
+
batch = CanvasSync::JobBatches::Batch.new
|
252
|
+
batch.description = "Some Batch" # Optional, but can be useful for debugging
|
253
|
+
|
254
|
+
batch.on(:complete, "SomeClass.on_complete", kw_param: 1)
|
255
|
+
batch.on(:success, "SomeClass.on_success", some_param: 'foo')
|
256
|
+
|
257
|
+
# Add context to the batch. Can be accessed as batch_context on any jobs within the batch.
|
258
|
+
# Nested Batches will have their contexts merged
|
259
|
+
batch.context = {
|
260
|
+
some_value: 'blah',
|
261
|
+
}
|
262
|
+
|
263
|
+
batch.jobs do
|
264
|
+
# Enqueue jobs like normal
|
265
|
+
end
|
266
|
+
```
|
267
|
+
|
268
|
+
#### Job Pools
|
269
|
+
A job pool is like a custom Sidekiq Queue. You can add jobs to it and it will empty itself out into one of the actual queues.
|
270
|
+
However, it adds some options for tweaking the logic:
|
271
|
+
- `concurrency` (default: `nil`) - Define how many jobs from the pool can run at once.
|
272
|
+
- `order` (default: `fifo`) - Define how the pool will empty itself
|
273
|
+
- `fifo` - First-In First-Out, a traditional queue
|
274
|
+
- `lifo` - Last-In First-Out
|
275
|
+
- `random` - Pluck and run jobs in random order
|
276
|
+
- `priority` - Execute jobs in a priority order (NB: Due to Redis, this priority-random, meaning that items with the same priority will be run in random order, not fifo)
|
277
|
+
- `clean_when_empty` (default: `true`) - Automatically clean the pool when it is empty
|
278
|
+
- `on_failed_job` (default `:wait`) - If a Job fails, should the pool `:continue` and still enqueue the next job or `:wait` for the job to succeed
|
279
|
+
|
280
|
+
Example:
|
281
|
+
```ruby
|
282
|
+
pool = CanvasSync::JobBatches::Pool.new(concurrency: 4, order: :priority, clean_when_empty: false)
|
283
|
+
pool_id = pool.pid
|
284
|
+
|
285
|
+
# Add a job to the pool
|
286
|
+
pool << {
|
287
|
+
job: SomeJob, # The Class of a ActiveJob Job or Sidekiq Worker
|
288
|
+
parameters: [1, 2, 3], # Array of params to pass th e Job
|
289
|
+
priority: 100, # Only effective if order=:priority, higher is higher
|
290
|
+
}
|
291
|
+
|
292
|
+
# Add many jobs to the pool
|
293
|
+
pool.add_jobs([
|
294
|
+
{
|
295
|
+
job: SomeJob, # The Class of a ActiveJob Job or Sidekiq Worker
|
296
|
+
parameters: [1, 2, 3], # Array of params to pass th e Job
|
297
|
+
priority: 100, # Only effective if order=:priority, higher is higher
|
298
|
+
},
|
299
|
+
# ...
|
300
|
+
])
|
301
|
+
|
302
|
+
# ...Later
|
303
|
+
CanvasSync::JobBatches::Pool.from_pid(pool_id).cleanup_redis
|
304
|
+
|
305
|
+
```
|
306
|
+
|
249
307
|
## Legacy Support
|
250
308
|
|
251
309
|
### Legacy Mappings
|
@@ -4,10 +4,13 @@ begin
|
|
4
4
|
rescue LoadError
|
5
5
|
end
|
6
6
|
|
7
|
+
require_relative './redis_model'
|
8
|
+
require_relative './redis_script'
|
7
9
|
require_relative './batch_aware_job'
|
8
10
|
require_relative "./callback"
|
9
11
|
require_relative "./context_hash"
|
10
12
|
require_relative "./status"
|
13
|
+
require_relative "./pool"
|
11
14
|
Dir[File.dirname(__FILE__) + "/jobs/*.rb"].each { |file| require file }
|
12
15
|
require_relative "./chain_builder"
|
13
16
|
|
@@ -17,24 +20,9 @@ require_relative "./chain_builder"
|
|
17
20
|
module CanvasSync
|
18
21
|
module JobBatches
|
19
22
|
class Batch
|
20
|
-
|
21
|
-
|
22
|
-
def self.batch_attr(key, read_only: true)
|
23
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
24
|
-
def #{key}=(value)
|
25
|
-
raise "#{key} is read-only once the batch has been started" if #{read_only.to_s} && (@initialized || @existing)
|
26
|
-
@#{key} = value
|
27
|
-
persist_bid_attr('#{key}', value)
|
28
|
-
end
|
23
|
+
include RedisModel
|
29
24
|
|
30
|
-
|
31
|
-
return @#{key} if defined?(@#{key})
|
32
|
-
if (@initialized || @existing)
|
33
|
-
@#{key} = read_bid_attr('#{key}')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
RUBY
|
37
|
-
end
|
25
|
+
class NoBlockGivenError < StandardError; end
|
38
26
|
|
39
27
|
delegate :redis, to: :class
|
40
28
|
|
@@ -47,16 +35,14 @@ module CanvasSync
|
|
47
35
|
@existing = !(!existing_bid || existing_bid.empty?) # Basically existing_bid.present?
|
48
36
|
@initialized = false
|
49
37
|
@bidkey = "BID-" + @bid.to_s
|
50
|
-
@pending_attrs = {}
|
51
|
-
@ready_to_queue = nil
|
52
38
|
self.created_at = Time.now.utc.to_f unless @existing
|
53
39
|
end
|
54
40
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
41
|
+
redis_attr :description
|
42
|
+
redis_attr :created_at
|
43
|
+
redis_attr :callback_queue, read_only: false
|
44
|
+
redis_attr :callback_params, :json
|
45
|
+
redis_attr :allow_context_changes
|
60
46
|
|
61
47
|
def context
|
62
48
|
return @context if defined?(@context)
|
@@ -122,29 +108,24 @@ module CanvasSync
|
|
122
108
|
@context&.save!
|
123
109
|
|
124
110
|
@initialized = true
|
111
|
+
else
|
112
|
+
assert_batch_is_open
|
125
113
|
end
|
126
114
|
|
127
|
-
job_queue = @ready_to_queue = []
|
128
|
-
|
129
115
|
begin
|
130
116
|
parent = Thread.current[:batch]
|
131
117
|
Thread.current[:batch] = self
|
132
118
|
yield
|
133
119
|
ensure
|
134
|
-
@ready_to_queue = nil
|
135
|
-
append_jobs(job_queue, parent_bid)
|
136
120
|
Thread.current[:batch] = parent
|
137
121
|
end
|
138
122
|
|
139
|
-
|
123
|
+
nil
|
140
124
|
end
|
141
125
|
|
142
126
|
def increment_job_queue(jid)
|
143
|
-
|
144
|
-
|
145
|
-
else
|
146
|
-
append_jobs([jid])
|
147
|
-
end
|
127
|
+
assert_batch_is_open
|
128
|
+
append_jobs([jid])
|
148
129
|
end
|
149
130
|
|
150
131
|
def invalidate_all
|
@@ -170,52 +151,42 @@ module CanvasSync
|
|
170
151
|
batch.parent ? valid && valid?(batch.parent) : valid
|
171
152
|
end
|
172
153
|
|
173
|
-
|
174
|
-
|
154
|
+
def self.with_batch(batch)
|
155
|
+
batch = self.new(batch) if batch.is_a?(String)
|
175
156
|
parent = Thread.current[:batch]
|
176
|
-
Thread.current[:batch] =
|
157
|
+
Thread.current[:batch] = batch
|
177
158
|
yield
|
178
159
|
ensure
|
179
160
|
Thread.current[:batch] = parent
|
180
161
|
end
|
181
162
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
if @initialized || @existing
|
186
|
-
redis do |r|
|
187
|
-
r.multi do
|
188
|
-
r.hset(@bidkey, attribute, value)
|
189
|
-
r.expire(@bidkey, BID_EXPIRE_TTL)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
else
|
193
|
-
@pending_attrs[attribute] = value
|
194
|
-
end
|
163
|
+
# Any Batches or Jobs created in the given block won't be assocaiated to the current batch
|
164
|
+
def self.without_batch(&blk)
|
165
|
+
with_batch(nil, &blk)
|
195
166
|
end
|
196
167
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
168
|
+
protected
|
169
|
+
|
170
|
+
def redis_key
|
171
|
+
@bidkey
|
201
172
|
end
|
202
173
|
|
203
|
-
|
204
|
-
|
205
|
-
|
174
|
+
private
|
175
|
+
|
176
|
+
def assert_batch_is_open
|
177
|
+
unless defined?(@closed)
|
178
|
+
redis do |r|
|
179
|
+
@closed = r.hget(@bidkey, 'success') == 'true'
|
180
|
+
end
|
206
181
|
end
|
207
|
-
|
182
|
+
raise "Cannot add jobs to Batch #{} bid - it has already entered the callback-stage" if @closed
|
208
183
|
end
|
209
184
|
|
210
|
-
def append_jobs(jids
|
185
|
+
def append_jobs(jids)
|
186
|
+
jids = jids.uniq
|
211
187
|
redis do |r|
|
212
188
|
r.multi do
|
213
|
-
if parent_bid
|
214
|
-
r.hincrby("BID-#{parent_bid}", "total", jids.size)
|
215
|
-
end
|
216
|
-
|
217
189
|
r.hincrby(@bidkey, "pending", jids.size)
|
218
|
-
r.hincrby(@bidkey, "total", jids.size)
|
219
190
|
r.expire(@bidkey, BID_EXPIRE_TTL)
|
220
191
|
|
221
192
|
if jids.size > 0
|
@@ -242,17 +213,6 @@ module CanvasSync
|
|
242
213
|
end
|
243
214
|
end
|
244
215
|
|
245
|
-
# if the batch failed, and has a parent, update the parent to show one pending and failed job
|
246
|
-
if parent_bid
|
247
|
-
redis do |r|
|
248
|
-
r.multi do
|
249
|
-
r.hincrby("BID-#{parent_bid}", "pending", 1)
|
250
|
-
r.sadd("BID-#{parent_bid}-failed", jid)
|
251
|
-
r.expire("BID-#{parent_bid}-failed", BID_EXPIRE_TTL)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
216
|
if pending.to_i == failed.to_i && children == complete
|
257
217
|
enqueue_callbacks(:complete, bid)
|
258
218
|
end
|
@@ -285,7 +245,7 @@ module CanvasSync
|
|
285
245
|
end
|
286
246
|
|
287
247
|
def process_successful_job(bid, jid)
|
288
|
-
_, failed, pending, children, complete, success,
|
248
|
+
_, failed, pending, children, complete, success, parent_bid = redis do |r|
|
289
249
|
r.multi do
|
290
250
|
r.srem("BID-#{bid}-failed", jid)
|
291
251
|
|
@@ -294,14 +254,16 @@ module CanvasSync
|
|
294
254
|
r.hincrby("BID-#{bid}", "children", 0)
|
295
255
|
r.scard("BID-#{bid}-batches-complete")
|
296
256
|
r.scard("BID-#{bid}-batches-success")
|
297
|
-
r.hget("BID-#{bid}", "total")
|
298
257
|
r.hget("BID-#{bid}", "parent_bid")
|
299
258
|
|
259
|
+
r.hincrby("BID-#{bid}", "successful-jobs", 1)
|
300
260
|
r.srem("BID-#{bid}-jids", jid)
|
301
261
|
r.expire("BID-#{bid}", BID_EXPIRE_TTL)
|
302
262
|
end
|
303
263
|
end
|
304
264
|
|
265
|
+
# TODO - There seems to be an issue where a :complete callback batch will occasionally run its job, but won't enqueue_callbacks()
|
266
|
+
|
305
267
|
all_success = pending.to_i.zero? && children == success
|
306
268
|
# if complete or successfull call complete callback (the complete callback may then call successful)
|
307
269
|
if (pending.to_i == failed.to_i && children == complete) || all_success
|
@@ -313,14 +275,15 @@ module CanvasSync
|
|
313
275
|
def enqueue_callbacks(event, bid)
|
314
276
|
batch_key = "BID-#{bid}"
|
315
277
|
callback_key = "#{batch_key}-callbacks-#{event}"
|
316
|
-
already_processed, _, callbacks, queue, parent_bid,
|
278
|
+
already_processed, _, callbacks, queue, parent_bid, callback_params = redis do |r|
|
279
|
+
return unless r.exists?(batch_key)
|
317
280
|
r.multi do
|
318
281
|
r.hget(batch_key, event)
|
319
282
|
r.hset(batch_key, event, true)
|
320
283
|
r.smembers(callback_key)
|
321
284
|
r.hget(batch_key, "callback_queue")
|
322
285
|
r.hget(batch_key, "parent_bid")
|
323
|
-
r.hget(batch_key, "
|
286
|
+
r.hget(batch_key, "callback_params")
|
324
287
|
end
|
325
288
|
end
|
326
289
|
|
@@ -328,6 +291,7 @@ module CanvasSync
|
|
328
291
|
|
329
292
|
queue ||= "default"
|
330
293
|
parent_bid = !parent_bid || parent_bid.empty? ? nil : parent_bid # Basically parent_bid.blank?
|
294
|
+
callback_params = JSON.parse(callback_params) if callback_params.present?
|
331
295
|
callback_args = callbacks.reduce([]) do |memo, jcb|
|
332
296
|
cb = JSON.load(jcb)
|
333
297
|
memo << [cb['callback'], event.to_s, cb['opts'], bid, parent_bid]
|
@@ -335,38 +299,32 @@ module CanvasSync
|
|
335
299
|
|
336
300
|
opts = {"bid" => bid, "event" => event}
|
337
301
|
|
338
|
-
|
339
|
-
|
340
|
-
# Extract opts from cb_args or use current
|
341
|
-
# Pass in stored event as callback finalize is processed on complete event
|
342
|
-
cb_opts = callback_args.first&.at(2) || opts
|
302
|
+
if callback_args.present? && !callback_params.present?
|
303
|
+
logger.debug {"Enqueue callback bid: #{bid} event: #{event} args: #{callback_args.inspect}"}
|
343
304
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
305
|
+
with_batch(parent_bid) do
|
306
|
+
cb_batch = self.new
|
307
|
+
cb_batch.callback_params = {
|
308
|
+
for_bid: bid,
|
309
|
+
event: event,
|
310
|
+
}
|
311
|
+
opts['callback_bid'] = cb_batch.bid
|
349
312
|
|
350
|
-
|
313
|
+
logger.debug {"Adding callback batch: #{cb_batch.bid} for batch: #{bid}"}
|
314
|
+
cb_batch.jobs do
|
315
|
+
push_callbacks callback_args, queue
|
316
|
+
end
|
317
|
+
end
|
351
318
|
end
|
352
319
|
|
353
|
-
|
354
|
-
|
355
|
-
if callback_args.empty?
|
356
|
-
# Finalize now
|
357
|
-
finalizer = Batch::Callback::Finalize.new
|
358
|
-
status = Status.new bid
|
359
|
-
finalizer.dispatch(status, opts)
|
360
|
-
else
|
361
|
-
# Otherwise finalize in sub batch complete callback
|
362
|
-
cb_batch = self.new
|
363
|
-
cb_batch.callback_batch = true
|
364
|
-
logger.debug {"Adding callback batch: #{cb_batch.bid} for batch: #{bid}"}
|
365
|
-
cb_batch.on(:complete, "#{Batch::Callback::Finalize.to_s}#dispatch", opts)
|
366
|
-
cb_batch.jobs do
|
367
|
-
push_callbacks callback_args, queue
|
368
|
-
end
|
320
|
+
if callback_params.present?
|
321
|
+
opts['origin'] = callback_params
|
369
322
|
end
|
323
|
+
|
324
|
+
logger.debug {"Run batch finalizer bid: #{bid} event: #{event} args: #{callback_args.inspect}"}
|
325
|
+
finalizer = Batch::Callback::Finalize.new
|
326
|
+
status = Status.new bid
|
327
|
+
finalizer.dispatch(status, opts)
|
370
328
|
end
|
371
329
|
|
372
330
|
def cleanup_redis(bid)
|
@@ -381,6 +339,7 @@ module CanvasSync
|
|
381
339
|
"BID-#{bid}-batches-success",
|
382
340
|
"BID-#{bid}-batches-complete",
|
383
341
|
"BID-#{bid}-batches-failed",
|
342
|
+
"BID-#{bid}-bids",
|
384
343
|
"BID-#{bid}-jids",
|
385
344
|
)
|
386
345
|
end
|
@@ -397,7 +356,7 @@ module CanvasSync
|
|
397
356
|
private
|
398
357
|
|
399
358
|
def push_callbacks(args, queue)
|
400
|
-
Batch::Callback::
|
359
|
+
Batch::Callback::worker_class.enqueue_all(args, queue)
|
401
360
|
end
|
402
361
|
end
|
403
362
|
end
|
@@ -2,6 +2,7 @@ module CanvasSync
|
|
2
2
|
module JobBatches
|
3
3
|
class Batch
|
4
4
|
module Callback
|
5
|
+
mattr_accessor :worker_class
|
5
6
|
|
6
7
|
VALID_CALLBACKS = %w[success complete dead].freeze
|
7
8
|
|
@@ -47,47 +48,34 @@ module CanvasSync
|
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
class SidekiqCallbackWorker
|
52
|
-
include ::Sidekiq::Worker
|
53
|
-
include CallbackWorkerCommon
|
54
|
-
|
55
|
-
def self.enqueue_all(args, queue)
|
56
|
-
return if args.empty?
|
57
|
-
|
58
|
-
::Sidekiq::Client.push_bulk(
|
59
|
-
'class' => self,
|
60
|
-
'args' => args,
|
61
|
-
'queue' => queue
|
62
|
-
)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
Worker = SidekiqCallbackWorker
|
66
|
-
else
|
67
|
-
Worker = ActiveJobCallbackWorker
|
68
|
-
end
|
51
|
+
worker_class = ActiveJobCallbackWorker
|
69
52
|
|
70
53
|
class Finalize
|
71
|
-
def dispatch
|
54
|
+
def dispatch(status, opts)
|
55
|
+
is_callback_batch = opts['origin'].present?
|
56
|
+
has_callback_batch = opts['callback_bid'].present?
|
57
|
+
|
72
58
|
bid = opts["bid"]
|
73
|
-
callback_bid = status.bid
|
74
59
|
event = opts["event"].to_sym
|
75
|
-
callback_batch = bid != callback_bid
|
76
60
|
|
77
|
-
Batch.logger.debug {"Finalize #{event} batch id: #{opts["bid"]}, callback batch id: #{callback_bid} callback_batch #{
|
61
|
+
Batch.logger.debug {"Finalize #{event} batch id: #{opts["bid"]}, callback batch id: #{callback_bid} callback_batch #{is_callback_batch}"}
|
78
62
|
|
79
63
|
batch_status = Status.new bid
|
80
64
|
send(event, bid, batch_status, batch_status.parent_bid)
|
81
65
|
|
82
|
-
|
83
|
-
|
84
|
-
|
66
|
+
if event == :success && !has_callback_batch
|
67
|
+
Batch.cleanup_redis(bid)
|
68
|
+
end
|
69
|
+
|
70
|
+
if event == :success && is_callback_batch && opts['origin']['event'].to_sym == :success
|
71
|
+
Batch.cleanup_redis(opts['origin']['for_bid'])
|
72
|
+
end
|
85
73
|
end
|
86
74
|
|
87
75
|
def success(bid, status, parent_bid)
|
88
76
|
return unless parent_bid
|
89
77
|
|
90
|
-
_, _, success, _, _, complete, pending, children, failure = Batch.redis do |r|
|
78
|
+
_, _, success, _, _, complete, pending, children, success, failure = Batch.redis do |r|
|
91
79
|
r.multi do
|
92
80
|
r.sadd("BID-#{parent_bid}-batches-success", bid)
|
93
81
|
r.expire("BID-#{parent_bid}-batches-success", Batch::BID_EXPIRE_TTL)
|
@@ -99,15 +87,21 @@ module CanvasSync
|
|
99
87
|
|
100
88
|
r.hincrby("BID-#{parent_bid}", "pending", 0)
|
101
89
|
r.hincrby("BID-#{parent_bid}", "children", 0)
|
90
|
+
r.scard("BID-#{parent_bid}-batches-success")
|
102
91
|
r.scard("BID-#{parent_bid}-failed")
|
103
92
|
end
|
104
93
|
end
|
105
|
-
|
106
|
-
#
|
94
|
+
|
95
|
+
# If the job finished successfully and parent batch is completed, call parent :complete callback
|
96
|
+
# Parent :success callback will be called by its :complete callback
|
107
97
|
if complete == children && pending == failure
|
108
98
|
Batch.logger.debug {"Finalize parent complete bid: #{parent_bid}"}
|
109
99
|
Batch.enqueue_callbacks(:complete, parent_bid)
|
110
100
|
end
|
101
|
+
if pending.to_i.zero? && children == success
|
102
|
+
Batch.logger.debug {"Finalize parent success bid: #{parent_bid}"}
|
103
|
+
Batch.enqueue_callbacks(:success, parent_bid)
|
104
|
+
end
|
111
105
|
end
|
112
106
|
|
113
107
|
def complete(bid, status, parent_bid)
|
@@ -119,10 +113,12 @@ module CanvasSync
|
|
119
113
|
end
|
120
114
|
end
|
121
115
|
|
122
|
-
#
|
116
|
+
# If the batch was successful run :success callback, which will call the parent's :complete callback (if necessary)
|
117
|
+
# Also, only trigger the success callback if the :complete callback_batch was successful
|
123
118
|
if pending.to_i.zero? && children == success
|
124
|
-
Batch.enqueue_callbacks(:success, bid)
|
119
|
+
# Batch.enqueue_callbacks(:success, bid)
|
125
120
|
|
121
|
+
# otherwise check for a parent and call its :complete if needed
|
126
122
|
elsif parent_bid
|
127
123
|
# if batch was not successfull check and see if its parent is complete
|
128
124
|
# if the parent is complete we trigger the complete callback
|