canvas_sync 0.17.23.beta6 → 0.17.24

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: 298b05c56dda9ca6d603c1242c25fce864b4d69d096f2559a22267546f2183cb
4
- data.tar.gz: d130e60ee19646e3d6cb817d63875bfdbd9358772c1dca25e49286c18cd0ca0d
3
+ metadata.gz: ff1d01575608d114952bb12803cae01cc2f4ff61c8ffeed78f18b247973926fa
4
+ data.tar.gz: ba3629041f491bb7bac12e03da3c896563c9595c77b58cec0d0c728f97168fcf
5
5
  SHA512:
6
- metadata.gz: d1b091aa6718f213dffc0a80985db5d736dcc4269365a8c7cdba713fc17ed256314b66183d050b952284374fc10f18b31018fcfee6fdb4fa9d185824fec73033
7
- data.tar.gz: b822704460aef2ea10664ff02de96de7f9baa240e3c1fbd19092a86160cad364ec8f42305882502b3aede3ad4972bd3f168716cba1c65bdd6e3b46014776f7ff
6
+ metadata.gz: 73ef3c21b2bb55276da6d5bd96a13b089117e47a04a117d4533822dc790eb2a62b2f8ac88fbfe122a4292e801542c49facef12554fd9a7c80426f699125d42b2
7
+ data.tar.gz: 29be22e24cb562c9decae8986b5e8a2b7f09da39a80e019edfe6f3cc994a90a2d53da1c9bae4e3d56640d630d7fbd8abca43e8bf946d35c211dae0a00833ef91
@@ -19,6 +19,8 @@ require_relative "./chain_builder"
19
19
 
20
20
  module CanvasSync
21
21
  module JobBatches
22
+ CURRENT_BATCH_THREAD_KEY = :job_batches_batch
23
+
22
24
  class Batch
23
25
  include RedisModel
24
26
 
@@ -76,14 +78,12 @@ module CanvasSync
76
78
  def on(event, callback, options = {})
77
79
  return unless Callback::VALID_CALLBACKS.include?(event.to_s)
78
80
  callback_key = "#{@bidkey}-callbacks-#{event}"
79
- redis do |r|
80
- r.multi do
81
- r.sadd(callback_key, JSON.unparse({
82
- callback: callback,
83
- opts: options
84
- }))
85
- r.expire(callback_key, BID_EXPIRE_TTL)
86
- end
81
+ redis.multi do |r|
82
+ r.sadd(callback_key, JSON.unparse({
83
+ callback: callback,
84
+ opts: options
85
+ }))
86
+ r.expire(callback_key, BID_EXPIRE_TTL)
87
87
  end
88
88
  end
89
89
 
@@ -91,18 +91,16 @@ module CanvasSync
91
91
  raise NoBlockGivenError unless block_given?
92
92
 
93
93
  if !@existing && !@initialized
94
- parent_bid = Thread.current[:batch]&.bid
94
+ parent_bid = Thread.current[CURRENT_BATCH_THREAD_KEY]&.bid
95
95
 
96
- redis do |r|
97
- r.multi do
98
- r.hset(@bidkey, "parent_bid", parent_bid.to_s) if parent_bid
99
- r.expire(@bidkey, BID_EXPIRE_TTL)
96
+ redis.multi do |r|
97
+ r.hset(@bidkey, "parent_bid", parent_bid.to_s) if parent_bid
98
+ r.expire(@bidkey, BID_EXPIRE_TTL)
100
99
 
101
- if parent_bid
102
- r.hincrby("BID-#{parent_bid}", "children", 1)
103
- r.expire("BID-#{parent_bid}", BID_EXPIRE_TTL)
104
- r.zadd("BID-#{parent_bid}-bids", created_at, bid)
105
- end
100
+ if parent_bid
101
+ r.hincrby("BID-#{parent_bid}", "children", 1)
102
+ r.expire("BID-#{parent_bid}", BID_EXPIRE_TTL)
103
+ r.zadd("BID-#{parent_bid}-bids", created_at, bid)
106
104
  end
107
105
  end
108
106
 
@@ -115,11 +113,11 @@ module CanvasSync
115
113
  end
116
114
 
117
115
  begin
118
- parent = Thread.current[:batch]
119
- Thread.current[:batch] = self
116
+ parent = Thread.current[CURRENT_BATCH_THREAD_KEY]
117
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = self
120
118
  yield
121
119
  ensure
122
- Thread.current[:batch] = parent
120
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = parent
123
121
  end
124
122
 
125
123
  nil
@@ -131,15 +129,11 @@ module CanvasSync
131
129
  end
132
130
 
133
131
  def invalidate_all
134
- redis do |r|
135
- r.setex("invalidated-bid-#{bid}", BID_EXPIRE_TTL, 1)
136
- end
132
+ redis.setex("invalidated-bid-#{bid}", BID_EXPIRE_TTL, 1)
137
133
  end
138
134
 
139
135
  def parent_bid
140
- redis do |r|
141
- r.hget(@bidkey, "parent_bid")
142
- end
136
+ redis.hget(@bidkey, "parent_bid")
143
137
  end
144
138
 
145
139
  def parent
@@ -149,7 +143,7 @@ module CanvasSync
149
143
  end
150
144
 
151
145
  def valid?(batch = self)
152
- valid = !redis { |r| r.exists?("invalidated-bid-#{batch.bid}") }
146
+ valid = !redis.exists?("invalidated-bid-#{batch.bid}")
153
147
  batch.parent ? valid && valid?(batch.parent) : valid
154
148
  end
155
149
 
@@ -162,23 +156,19 @@ module CanvasSync
162
156
  let_close!
163
157
  end
164
158
  else
165
- redis do |r|
166
- r.hset(@bidkey, 'keep_open', true)
167
- end
159
+ redis.hset(@bidkey, 'keep_open', true)
168
160
  end
169
161
  end
170
162
 
171
163
  def let_close!
172
- _, failed, pending, children, complete, success = redis do |r|
173
- r.multi do
174
- r.hset(@bidkey, 'keep_open', false)
175
-
176
- r.scard("BID-#{bid}-failed")
177
- r.hincrby("BID-#{bid}", "pending", 0)
178
- r.hincrby("BID-#{bid}", "children", 0)
179
- r.scard("BID-#{bid}-batches-complete")
180
- r.scard("BID-#{bid}-batches-success")
181
- end
164
+ _, failed, pending, children, complete, success = redis.multi do |r|
165
+ r.hset(@bidkey, 'keep_open', false)
166
+
167
+ r.scard("BID-#{bid}-failed")
168
+ r.hincrby("BID-#{bid}", "pending", 0)
169
+ r.hincrby("BID-#{bid}", "children", 0)
170
+ r.scard("BID-#{bid}-batches-complete")
171
+ r.scard("BID-#{bid}-batches-success")
182
172
  end
183
173
 
184
174
  all_success = pending.to_i.zero? && children == success
@@ -191,11 +181,11 @@ module CanvasSync
191
181
 
192
182
  def self.with_batch(batch)
193
183
  batch = self.new(batch) if batch.is_a?(String)
194
- parent = Thread.current[:batch]
195
- Thread.current[:batch] = batch
184
+ parent = Thread.current[CURRENT_BATCH_THREAD_KEY]
185
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = batch
196
186
  yield
197
187
  ensure
198
- Thread.current[:batch] = parent
188
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = parent
199
189
  end
200
190
 
201
191
  # Any Batches or Jobs created in the given block won't be assocaiated to the current batch
@@ -211,18 +201,14 @@ module CanvasSync
211
201
 
212
202
  def flush_pending_attrs
213
203
  super
214
- redis do |r|
215
- r.zadd("batches", created_at, bid)
216
- end
204
+ redis.zadd("batches", created_at, bid)
217
205
  end
218
206
 
219
207
  private
220
208
 
221
209
  def assert_batch_is_open
222
210
  unless defined?(@closed)
223
- redis do |r|
224
- @closed = r.hget(@bidkey, 'success') == 'true'
225
- end
211
+ @closed = redis.hget(@bidkey, 'success') == 'true'
226
212
  end
227
213
  raise "Cannot add jobs to Batch #{} bid - it has already entered the callback-stage" if @closed
228
214
  end
@@ -234,7 +220,7 @@ module CanvasSync
234
220
  redis do |r|
235
221
  tme = Time.now.utc.to_f
236
222
  added = r.zadd(@bidkey + "-jids", jids.map{|jid| [tme, jid] }, nx: true)
237
- r.multi do
223
+ r.multi do |r|
238
224
  r.hincrby(@bidkey, "pending", added)
239
225
  r.hincrby(@bidkey, "job_count", added)
240
226
  r.expire(@bidkey, BID_EXPIRE_TTL)
@@ -244,6 +230,14 @@ module CanvasSync
244
230
  end
245
231
 
246
232
  class << self
233
+ def current
234
+ Thread.current[CURRENT_BATCH_THREAD_KEY]
235
+ end
236
+
237
+ def current_context
238
+ current&.context || {}
239
+ end
240
+
247
241
  def process_failed_job(bid, jid)
248
242
  _, pending, failed, children, complete, parent_bid = redis do |r|
249
243
  return unless r.exists?("BID-#{bid}")
@@ -283,11 +277,9 @@ module CanvasSync
283
277
  end
284
278
 
285
279
  if parent_bid
286
- redis do |r|
287
- r.multi do
288
- r.sadd("BID-#{parent_bid}-dead", jid)
289
- r.expire("BID-#{parent_bid}-dead", BID_EXPIRE_TTL)
290
- end
280
+ redis.multi do
281
+ r.sadd("BID-#{parent_bid}-dead", jid)
282
+ r.expire("BID-#{parent_bid}-dead", BID_EXPIRE_TTL)
291
283
  end
292
284
  end
293
285
 
@@ -413,8 +405,21 @@ module CanvasSync
413
405
  cleanup_redis(bid)
414
406
  end
415
407
 
416
- def redis(*args, &blk)
417
- defined?(::Sidekiq) ? ::Sidekiq.redis(*args, &blk) : nil # TODO
408
+ def redis(&blk)
409
+ return RedisProxy.new unless block_given?
410
+
411
+ if Thread.current[:job_batches_redis]
412
+ yield Thread.current[:job_batches_redis]
413
+ elsif defined?(::Sidekiq)
414
+ ::Sidekiq.redis do |r|
415
+ Thread.current[:job_batches_redis] = r
416
+ yield r
417
+ ensure
418
+ Thread.current[:job_batches_redis] = nil
419
+ end
420
+ else
421
+ # TODO
422
+ end
418
423
  end
419
424
 
420
425
  def logger
@@ -433,6 +438,42 @@ module CanvasSync
433
438
  end
434
439
  end
435
440
  end
441
+
442
+ class RedisProxy
443
+ def multi(*args, &block)
444
+ Batch.redis do |r|
445
+ if block.arity == 1
446
+ r.multi(*args) do
447
+ block.call(r)
448
+ end
449
+ else
450
+ r.multi(*args, &block)
451
+ end
452
+ end
453
+ end
454
+
455
+ def pipelined(*args, &block)
456
+ Batch.redis do |r|
457
+ if block.arity == 1
458
+ r.pipelined(*args) do
459
+ block.call(r)
460
+ end
461
+ else
462
+ r.pipelined(*args, &block)
463
+ end
464
+ end
465
+ end
466
+
467
+ def method_missing(method_name, *arguments, &block)
468
+ Batch.redis do |r|
469
+ r.send(method_name, *arguments, &block)
470
+ end
471
+ end
472
+
473
+ def respond_to_missing?(method_name, include_private = false)
474
+ super || Redis.method_defined?(method_name)
475
+ end
476
+ end
436
477
  end
437
478
 
438
479
  ActiveJob::Base.include BatchAwareJob
@@ -6,17 +6,17 @@ module CanvasSync
6
6
  included do
7
7
  around_perform do |job, block|
8
8
  if (@bid) # This _must_ be @bid - not just bid
9
- prev_batch = Thread.current[:batch]
9
+ prev_batch = Thread.current[CURRENT_BATCH_THREAD_KEY]
10
10
  begin
11
- Thread.current[:batch] = Batch.new(@bid)
11
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = Batch.new(@bid)
12
12
  block.call
13
- Thread.current[:batch].save_context_changes
13
+ Thread.current[CURRENT_BATCH_THREAD_KEY].save_context_changes
14
14
  Batch.process_successful_job(@bid, job_id)
15
15
  rescue
16
16
  Batch.process_failed_job(@bid, job_id)
17
17
  raise
18
18
  ensure
19
- Thread.current[:batch] = prev_batch
19
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = prev_batch
20
20
  end
21
21
  else
22
22
  block.call
@@ -24,7 +24,7 @@ module CanvasSync
24
24
  end
25
25
 
26
26
  around_enqueue do |job, block|
27
- if (batch = Thread.current[:batch])
27
+ if (batch = Thread.current[CURRENT_BATCH_THREAD_KEY])
28
28
  @bid = batch.bid
29
29
  batch.increment_job_queue(job_id) if @bid
30
30
  end
@@ -33,11 +33,11 @@ module CanvasSync
33
33
  end
34
34
 
35
35
  def bid
36
- @bid || Thread.current[:batch]&.bid
36
+ @bid || Thread.current[CURRENT_BATCH_THREAD_KEY]&.bid
37
37
  end
38
38
 
39
39
  def batch
40
- Thread.current[:batch]
40
+ Thread.current[CURRENT_BATCH_THREAD_KEY]
41
41
  end
42
42
 
43
43
  def batch_context
@@ -64,18 +64,14 @@ module CanvasSync
64
64
  let_close!
65
65
  end
66
66
  else
67
- redis do |r|
68
- r.hset(redis_key, 'keep_open', true)
69
- end
67
+ redis.hset(redis_key, 'keep_open', true)
70
68
  end
71
69
  end
72
70
 
73
71
  def let_close!
74
- _, active_count = redis do |r|
75
- r.multi do
76
- r.hset(redis_key, 'keep_open', false)
77
- r.hincrby(redis_key, "active_count", 0)
78
- end
72
+ _, active_count = redis.multi do |r|
73
+ r.hset(redis_key, 'keep_open', false)
74
+ r.hincrby(redis_key, "active_count", 0)
79
75
  end
80
76
 
81
77
  if active_count == 0 && pending_count == 0
@@ -95,35 +91,38 @@ module CanvasSync
95
91
  end
96
92
 
97
93
  def active_count
98
- redis do |r|
99
- r.hincrby(redis_key, "active_count", 0)
100
- end
94
+ redis.hincrby(redis_key, "active_count", 0)
101
95
  end
102
96
 
103
97
  def pending_count
104
98
  jobs_key = "#{redis_key}-jobs"
105
99
  order = self.order || 'fifo'
106
- redis do |r|
107
- case order.to_sym
108
- when :fifo, :lifo
109
- r.llen(jobs_key)
110
- when :random
111
- r.scard(jobs_key)
112
- when :priority
113
- r.zcard(jobs_key)
114
- end
100
+ case order.to_sym
101
+ when :fifo, :lifo
102
+ redis.llen(jobs_key)
103
+ when :random
104
+ redis.scard(jobs_key)
105
+ when :priority
106
+ redis.zcard(jobs_key)
115
107
  end
116
108
  end
117
109
 
118
110
  def job_checked_in(status, options)
119
- active_count = redis do |r|
111
+ active_count, pending_count = redis do |r|
120
112
  return unless r.exists?(redis_key)
121
- r.hincrby(redis_key, "active_count", -1)
113
+
114
+ # Make sure this is loaded outside of the pipeline
115
+ self.order
116
+
117
+ redis.multi do
118
+ r.hincrby(redis_key, "active_count", -1)
119
+ self.pending_count
120
+ end
122
121
  end
123
122
 
124
123
  added_count = refill_allotment
125
- if active_count == 0 && added_count == 0
126
- if clean_when_empty && redis {|r| r.hget(redis_key, 'keep_open') } != 'true'
124
+ if active_count == 0 && added_count == 0 && pending_count == 0
125
+ if clean_when_empty && redis.hget(redis_key, 'keep_open') != 'true'
127
126
  cleanup_redis
128
127
  end
129
128
  end
@@ -175,18 +174,16 @@ module CanvasSync
175
174
  job_json = JSON.unparse(ActiveJob::Arguments.serialize([job_desc]))
176
175
  order = self.order
177
176
 
178
- redis do |r|
179
- r.multi do
180
- case order.to_sym
181
- when :fifo, :lifo
182
- r.rpush(jobs_key, job_json)
183
- when :random
184
- r.sadd(jobs_key, job_json)
185
- when :priority
186
- r.zadd(jobs_key, job_desc[:priority] || 0, job_json)
187
- end
188
- r.expire(jobs_key, Batch::BID_EXPIRE_TTL)
177
+ redis.multi do |r|
178
+ case order.to_sym
179
+ when :fifo, :lifo
180
+ r.rpush(jobs_key, job_json)
181
+ when :random
182
+ r.sadd(jobs_key, job_json)
183
+ when :priority
184
+ r.zadd(jobs_key, job_desc[:priority] || 0, job_json)
189
185
  end
186
+ r.expire(jobs_key, Batch::BID_EXPIRE_TTL)
190
187
  end
191
188
  end
192
189
 
@@ -194,18 +191,15 @@ module CanvasSync
194
191
  jobs_key = "#{redis_key}-jobs"
195
192
  order = self.order
196
193
 
197
- job_json = nil
198
- redis do |r|
199
- job_json = case order.to_sym
200
- when :fifo
201
- r.lpop(jobs_key)
202
- when :lifo
203
- r.rpop(jobs_key)
204
- when :random
205
- r.spop(jobs_key)
206
- when :priority
207
- r.zpopmax(jobs_key)
208
- end
194
+ job_json = case order.to_sym
195
+ when :fifo
196
+ redis.lpop(jobs_key)
197
+ when :lifo
198
+ redis.rpop(jobs_key)
199
+ when :random
200
+ redis.spop(jobs_key)
201
+ when :priority
202
+ redis.zpopmax(jobs_key)
209
203
  end
210
204
 
211
205
  return nil unless job_json.present?
@@ -218,13 +212,9 @@ module CanvasSync
218
212
  end
219
213
  delegate :redis, to: :class
220
214
 
221
- protected
222
-
223
215
  def flush_pending_attrs
224
216
  super
225
- redis do |r|
226
- r.zadd("pools", created_at, pid)
227
- end
217
+ redis.zadd("pools", created_at, pid)
228
218
  end
229
219
 
230
220
  private
@@ -8,11 +8,11 @@ module CanvasSync
8
8
  module Sidekiq
9
9
  module WorkerExtension
10
10
  def bid
11
- Thread.current[:batch].bid
11
+ Thread.current[CURRENT_BATCH_THREAD_KEY].bid
12
12
  end
13
13
 
14
14
  def batch
15
- Thread.current[:batch]
15
+ Thread.current[CURRENT_BATCH_THREAD_KEY]
16
16
  end
17
17
 
18
18
  def batch_context
@@ -42,7 +42,7 @@ module CanvasSync
42
42
 
43
43
  class ClientMiddleware
44
44
  def call(_worker, msg, _queue, _redis_pool = nil)
45
- if (batch = Thread.current[:batch]) && should_handle_batch?(msg)
45
+ if (batch = Thread.current[CURRENT_BATCH_THREAD_KEY]) && should_handle_batch?(msg)
46
46
  batch.increment_job_queue(msg['jid']) if (msg[:bid] = batch.bid)
47
47
  end
48
48
  yield
@@ -57,17 +57,17 @@ module CanvasSync
57
57
  class ServerMiddleware
58
58
  def call(_worker, msg, _queue)
59
59
  if (bid = msg['bid'])
60
- prev_batch = Thread.current[:batch]
60
+ prev_batch = Thread.current[CURRENT_BATCH_THREAD_KEY]
61
61
  begin
62
- Thread.current[:batch] = Batch.new(bid)
62
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = Batch.new(bid)
63
63
  yield
64
- Thread.current[:batch].save_context_changes
64
+ Thread.current[CURRENT_BATCH_THREAD_KEY].save_context_changes
65
65
  Batch.process_successful_job(bid, msg['jid'])
66
66
  rescue
67
67
  Batch.process_failed_job(bid, msg['jid'])
68
68
  raise
69
69
  ensure
70
- Thread.current[:batch] = prev_batch
70
+ Thread.current[CURRENT_BATCH_THREAD_KEY] = prev_batch
71
71
  end
72
72
  else
73
73
  yield
@@ -9,7 +9,7 @@ module CanvasSync
9
9
  # will be started for each term in that scope. :models should be an array of
10
10
  # models to sync.
11
11
  def perform(options)
12
- CanvasSync.get_canvas_sync_client(batch_context).terms("self").all_pages!.each do |term_params|
12
+ CanvasSync.get_canvas_sync_client(batch_context).terms("self", workflow_state: ['all']).all_pages!.each do |term_params|
13
13
  if account_id = batch_context[:account_id]
14
14
  # These branches are primarily to support Legacy apps
15
15
  if Term.respond_to?(:create_or_update) && Term.method(:create_or_update).arity.abs == 2
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.17.23.beta6".freeze
2
+ VERSION = "0.17.24".freeze
3
3
  end