canvas_sync 0.22.0.beta6 → 0.22.0.beta8

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: 125eb3db0c41f8fe1f4555b8346e6c90342bbe1f3c3fe6e2f5c664040f1c4fe7
4
- data.tar.gz: 4651404b9891212888ed31d38dee17090be15b108950b2e4631da6083a0dd5c8
3
+ metadata.gz: d547f65f6811b0e9016de79ad87cff6789a82bc1d02b100c0280a6591a7b44c5
4
+ data.tar.gz: 12bc5403297ceb4b13b1c29003f7ca8349b2ca4c7f54236fcc44c306d8cd56fc
5
5
  SHA512:
6
- metadata.gz: f52b68c339cf00addfefe062b62b3e6fc2b7ec691ecb8a82ed3be14020a5988a89f57d207f35a7fa4c4a566771650cbbff4d063e08686082b8633625f4596869
7
- data.tar.gz: 114247208144ff9999ccfedb0aa44363212bf6648f22f8ed728f9462efda03a5620e209f9011105b7ef2adedbacb687a9491aae4850cde52527679cf29a7b46a
6
+ metadata.gz: f6e4f2cb3de6d071837e29fbdbafa2f628018d82f302658e0a24a181bb2d5c00557372972c77ef924a6243f8e2fd861ef6a9488c25e2018092265398b589d303
7
+ data.tar.gz: 7b21c43a71b7c44674e89afcd0b55996ccac7dae346fc917304e95be9d01870580a46b117ff241e81fa1fde10594e6fc1c12d8f0b16be7cf6295fa1bebb04461
@@ -19,7 +19,7 @@ module CanvasSync::JobUniqueness
19
19
 
20
20
  class SidekiqLockContext < LockContext
21
21
  def job_scheduled_at
22
- @job_instance["at"]
22
+ @job_instance&.[]("at")
23
23
  end
24
24
 
25
25
  def reenqueue(schedule_in:)
@@ -6,18 +6,23 @@ module CanvasSync::JobUniqueness
6
6
  context_class.new(data, **kwargs)
7
7
  end
8
8
 
9
+ attr_reader :lock_id
10
+
9
11
  # { job_clazz, jid, queue, args?, kwargs?, base_key? }
10
12
  def initialize(data, job_instance: nil, config: nil)
11
13
  @base_key = data[:base_key]
12
14
  @context_data = data
13
15
  @job_instance = job_instance
14
16
  @config = config || @context_data[:config]
17
+
18
+ @lock_id ||= data[:lid] || Thread.current[:unique_jobs_previous_context]&.lock_id || job_id
15
19
  end
16
20
 
17
21
  # This is primarily for rehydrating in a Batch Callback, so it is unlikely that args and kwargs are needed.
18
22
  # Honestly, base_key and job_clazz are probably the only needed values
19
23
  def serialize
20
24
  {
25
+ lid: lock_id,
21
26
  clazz: self.class.to_s,
22
27
  job_clazz: @context_data[:job_clazz].to_s,
23
28
  jid: @context_data[:jid],
@@ -29,6 +34,7 @@ module CanvasSync::JobUniqueness
29
34
  # Properties to cache on the serialized Job object to prevent issues arising from code changes between enqueue and perform
30
35
  def cache_data
31
36
  {
37
+ lid: lock_id,
32
38
  base_key: base_key,
33
39
  job_score: job_score,
34
40
  # TODO Should config also be cached on the Job at time of enqueue?
@@ -14,7 +14,9 @@ module CanvasSync::JobUniqueness
14
14
 
15
15
  def initialize(key, lock_context, redis_pool = nil)
16
16
  @lock_context = lock_context
17
- @job_id = lock_context.job_id
17
+ # We use the "lock_id" (which is just the first JID that a job appeared as) so that Unlock batches may properly unlock the batch
18
+ # TODO For locks that do use a wrapping Batch, it may be nice to use the BID here instead
19
+ @job_id = lock_context.lock_id
18
20
  @item = lock_context
19
21
  @key = SidekiqUniqueJobs::Key.new(key)
20
22
 
@@ -28,7 +30,7 @@ module CanvasSync::JobUniqueness
28
30
  :"limit" => lcfg[:limit],
29
31
  })
30
32
 
31
- @redis_pool = redis_pool
33
+ @redis_pool = redis_pool
32
34
  end
33
35
 
34
36
  def locked_jids
@@ -4,12 +4,12 @@ module CanvasSync::JobUniqueness
4
4
  valid_for :perform
5
5
 
6
6
  def call
7
- Thread.current[:unique_jobs_previous_jid] = lock_context.job_id
7
+ Thread.current[:unique_jobs_previous_context] = lock_context
8
8
  rescheduled = lock_context.reenqueue(
9
9
  schedule_in: schedule_in,
10
10
  )
11
11
  ensure
12
- Thread.current[:unique_jobs_previous_jid] = nil
12
+ Thread.current[:unique_jobs_previous_context] = nil
13
13
  end
14
14
 
15
15
  def schedule_in
@@ -43,7 +43,7 @@ module CanvasSync::JobUniqueness
43
43
  end
44
44
 
45
45
  def wrap_in_batch(&blk)
46
- if Thread.current[:unique_jobs_previous_jid] # Ensure we don't re-wrap in a batch when rescheduling
46
+ if Thread.current[:unique_jobs_previous_context] # Ensure we don't re-wrap in a batch when rescheduling
47
47
  return blk.call
48
48
  end
49
49
 
@@ -74,7 +74,7 @@ module CanvasSync::JobUniqueness
74
74
  CanvasSync::JobUniqueness.logger.debug("Context data: #{opts[:lock_context]}")
75
75
  strategy_class = opts[:lock_strategy].constantize
76
76
  lock_context = LockContext.from_serialized(opts[:lock_context])
77
- CanvasSync::JobUniqueness.logger.debug("Rehydrated LockContext: #{lock_context.job_id} #{lock_context.debug_data}")
77
+ CanvasSync::JobUniqueness.logger.debug("Rehydrated LockContext: #{lock_context.lock_id} #{lock_context.debug_data}")
78
78
  strategy = strategy_class.new(lock_context)
79
79
  # TODO Should this route through LockContext#handle_lifecycle!?
80
80
  strategy.batch_callback(opts[:event].to_sym, batch_status)
@@ -83,13 +83,14 @@ module CanvasSync::JobUniqueness
83
83
  def lock!(purpose, wait: nil)
84
84
  locked = nil
85
85
  if purpose == :enqueue
86
- if Thread.current[:unique_jobs_previous_jid].present?
87
- locked = locksmith.swap_locks(Thread.current[:unique_jobs_previous_jid])
88
- else
89
- locked = locksmith.lock()
90
- end
86
+ # We don't need to swap_locks anymore because we maintain a consistent lock_id across re-enqueues
87
+ # if Thread.current[:unique_jobs_previous_context].present?
88
+ # locked = locksmith.swap_locks(Thread.current[:unique_jobs_previous_context].job_id)
89
+ # else
90
+ locked = locksmith.lock()
91
+ # end
91
92
  elsif purpose == :perform
92
- locked = locksmith.execute { lock_context.job_id }
93
+ locked = locksmith.execute { lock_context.lock_id }
93
94
  end
94
95
 
95
96
  CanvasSync::JobUniqueness.logger.debug { "Requested lock of #{key} for #{purpose} - (#{locked || 'Not Obtained!'})" }
@@ -98,7 +99,7 @@ module CanvasSync::JobUniqueness
98
99
  end
99
100
 
100
101
  def unlock()
101
- CanvasSync::JobUniqueness.logger.debug { "Trying to unlock #{key} - (#{result || 'Not Unlocked!'})" }
102
+ CanvasSync::JobUniqueness.logger.debug { "Trying to unlock #{key} for LID #{lock_context.lock_id}" }
102
103
  result = locksmith.unlock
103
104
  CanvasSync::JobUniqueness.logger.debug { "Unlocked #{key} - (#{result || 'Not Unlocked!'})" }
104
105
  end
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.22.0.beta6".freeze
2
+ VERSION = "0.22.0.beta8".freeze
3
3
  end
@@ -6,7 +6,7 @@ RSpec.describe CanvasSync::JobUniqueness::OnConflict::Reschedule do
6
6
 
7
7
  it "calls reenqueue" do
8
8
  expect(lock_context).to receive(:reenqueue) do |*args, **kwargs|
9
- expect(Thread.current[:unique_jobs_previous_jid]).to be_present
9
+ expect(Thread.current[:unique_jobs_previous_context]).to be_present
10
10
  end
11
11
  on_conflict.call
12
12
  end
@@ -1,6 +1,9 @@
1
1
  require_relative "../spec_helper"
2
2
  require "canvas_sync/job_uniqueness/job_uniqueness"
3
3
 
4
+ require 'redis'
5
+ Redis.silence_deprecations = true
6
+
4
7
  Dir[File.join(File.dirname(__FILE__), "./support/**/*.rb")].sort.each { |f| require f }
5
8
 
6
9
  Sidekiq::Testing.server_middleware do |chain|
@@ -9,11 +9,11 @@ RSpec.describe CanvasSync::JobUniqueness::Strategy::Base do
9
9
 
10
10
  describe '#wrap_in_batch' do
11
11
  it 'does not wrap if re-enqueuing' do
12
- Thread.current[:unique_jobs_previous_jid] = "j100"
12
+ Thread.current[:unique_jobs_previous_context] = context
13
13
  expect(CanvasSync::JobBatches::Batch).not_to receive(:new)
14
14
  strategy.send(:wrap_in_batch, &->{ })
15
15
  ensure
16
- Thread.current[:unique_jobs_previous_jid] = nil
16
+ Thread.current[:unique_jobs_previous_context] = nil
17
17
  end
18
18
 
19
19
  context 'when the job fails' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.0.beta6
4
+ version: 0.22.0.beta8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure CustomDev