canvas_sync 0.22.0.beta8 → 0.22.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: d547f65f6811b0e9016de79ad87cff6789a82bc1d02b100c0280a6591a7b44c5
4
- data.tar.gz: 12bc5403297ceb4b13b1c29003f7ca8349b2ca4c7f54236fcc44c306d8cd56fc
3
+ metadata.gz: b659edf35a8c6f427f847142d4627920cc19effabfe7fb5ad2ccb960884cf47c
4
+ data.tar.gz: 3264f9b298a5fcbf251a6ccd927ce20133598ed1b9fdd8adf3a728ef90a4e080
5
5
  SHA512:
6
- metadata.gz: f6e4f2cb3de6d071837e29fbdbafa2f628018d82f302658e0a24a181bb2d5c00557372972c77ef924a6243f8e2fd861ef6a9488c25e2018092265398b589d303
7
- data.tar.gz: 7b21c43a71b7c44674e89afcd0b55996ccac7dae346fc917304e95be9d01870580a46b117ff241e81fa1fde10594e6fc1c12d8f0b16be7cf6295fa1bebb04461
6
+ metadata.gz: a9c7add460f50301b9f404880e9f6ac2fc57996f1e4c8928f2c52b9bfa5f4973f6cc3c531729763a40de6cce127b86aed70b88ea11fc2119e9fe1856f81a4996
7
+ data.tar.gz: 7d5951ebd7f02917344ea94c23d4f7e5d467d7d803be2944ab1d073aa207acca55a065aa8e2b9145f129154c1ed10b9fb2d14b0692c1e1d8ec21a99f042dab8a
@@ -45,7 +45,7 @@ module CanvasSync::JobBatches
45
45
 
46
46
  def call(_worker, msg, _queue, _redis_pool = nil)
47
47
  if (batch = Thread.current[CURRENT_BATCH_THREAD_KEY]) && should_handle_batch?(msg)
48
- batch.increment_job_queue(msg['jid']) if (msg[:bid] = batch.bid)
48
+ batch.increment_job_queue(msg['jid']) if (msg['bid'] = batch.bid)
49
49
  end
50
50
  yield
51
51
  end
@@ -41,7 +41,7 @@ module CanvasSync::JobUniqueness
41
41
 
42
42
  def deserialize(data)
43
43
  super
44
- @uniqueness_cache_data = data['uniqueness_cache_data'].symbolize_keys
44
+ @uniqueness_cache_data = data['uniqueness_cache_data']&.symbolize_keys
45
45
  end
46
46
 
47
47
  def uniqueness_lock_context
@@ -38,7 +38,7 @@ module CanvasSync::JobUniqueness
38
38
  queue: msg['queue'],
39
39
  args: msg['args'],
40
40
  # kwargs: msg['kwargs'],
41
- **(msg['uniqueness_cache_data'] || {}),
41
+ **(msg['uniqueness_cache_data']&.symbolize_keys || {}),
42
42
  }, job_instance: msg)
43
43
  end
44
44
 
@@ -58,7 +58,7 @@ module CanvasSync::JobUniqueness
58
58
  def call(_worker, msg, _queue, _redis_pool = nil, &blk)
59
59
  ctx = lock_context(msg)
60
60
  return blk.call unless ctx
61
- msg['uniqueness_cache_data'] = ctx.cache_data
61
+ msg['uniqueness_cache_data'] = ctx.cache_data.stringify_keys
62
62
  ctx.handle_lifecycle!(:enqueue, &blk)
63
63
  end
64
64
  end
@@ -15,11 +15,11 @@ module CanvasSync::JobUniqueness
15
15
  @job_instance = job_instance
16
16
  @config = config || @context_data[:config]
17
17
 
18
+ # TODO Consider (somewhere) updating the lock_id to the BID of the wrapping Batch (when applicable)
18
19
  @lock_id ||= data[:lid] || Thread.current[:unique_jobs_previous_context]&.lock_id || job_id
19
20
  end
20
21
 
21
22
  # This is primarily for rehydrating in a Batch Callback, so it is unlikely that args and kwargs are needed.
22
- # Honestly, base_key and job_clazz are probably the only needed values
23
23
  def serialize
24
24
  {
25
25
  lid: lock_id,
@@ -44,6 +44,7 @@ module CanvasSync::JobUniqueness
44
44
 
45
45
  def debug_data
46
46
  {
47
+ lid: lock_id,
47
48
  context_class: self.class.to_s,
48
49
  job_class: job_class.to_s,
49
50
  queue: job_queue,
@@ -152,7 +153,6 @@ module CanvasSync::JobUniqueness
152
153
  # @yieldreturn [void] the yield is irrelevant, it only provides a mechanism in
153
154
  # one specific situation to yield back to the middleware.
154
155
  def call_conflict_strategy(origin)
155
- new_job_id = nil
156
156
  strategy = conflict_strategy_for(origin)
157
157
 
158
158
  strategy.call
@@ -14,9 +14,7 @@ module CanvasSync::JobUniqueness
14
14
 
15
15
  def initialize(key, lock_context, redis_pool = nil)
16
16
  @lock_context = lock_context
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
17
+ @job_id = lock_context.lock_id # Yes, .lock_id is intentional
20
18
  @item = lock_context
21
19
  @key = SidekiqUniqueJobs::Key.new(key)
22
20
 
@@ -62,7 +62,7 @@ module CanvasSync::JobUniqueness
62
62
  })
63
63
  end
64
64
 
65
- CanvasSync::JobUniqueness.logger.debug("Wrapped job in Locking Batch #{batch.bid} for #{key}")
65
+ CanvasSync::JobUniqueness.logger.debug("Wrapped job (#{lock_context.lock_id}) in Locking Batch #{batch.bid} for #{key}")
66
66
 
67
67
  batch.jobs do
68
68
  return blk.call
@@ -83,12 +83,7 @@ module CanvasSync::JobUniqueness
83
83
  def lock!(purpose, wait: nil)
84
84
  locked = nil
85
85
  if purpose == :enqueue
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
86
  locked = locksmith.lock()
91
- # end
92
87
  elsif purpose == :perform
93
88
  locked = locksmith.execute { lock_context.lock_id }
94
89
  end
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.22.0.beta8".freeze
2
+ VERSION = "0.22.0".freeze
3
3
  end
@@ -74,7 +74,7 @@ RSpec.describe CanvasSync::JobBatches::Compat::Sidekiq do
74
74
  it 'assigns bid to msg' do
75
75
  msg = { 'jid' => jid }
76
76
  subject.call(nil, msg, nil) {}
77
- expect(msg[:bid]).to eq(bid)
77
+ expect(msg['bid']).to eq(bid)
78
78
  end
79
79
  end
80
80
  end
@@ -21,4 +21,43 @@ RSpec.describe CanvasSync::JobUniqueness::OnConflict::Reschedule do
21
21
  lock_context2.handle_lifecycle!(:enqueue) {}
22
22
  lock_context2.handle_lifecycle!(:perform) {}
23
23
  end
24
+
25
+ it "maintains a consistent lock_id" do
26
+ TestWorker.clear
27
+ TestWorker.unique_job_options.merge!({ strategy: :while_executing, on_conflict: :reschedule })
28
+
29
+ lock_context.handle_lifecycle!(:enqueue) {}
30
+ lock_context.handle_lifecycle!(:perform) {}
31
+
32
+ TestWorker.perform_async
33
+ j1 = TestWorker.jobs[0]
34
+ TestWorker.perform_one
35
+ j2 = TestWorker.jobs[0]
36
+
37
+ expect(j1).not_to eq(j2)
38
+ expect(j1['uniqueness_cache_data']['lid']).to be_present
39
+ expect(j1['uniqueness_cache_data']['lid']).to eq(j2['uniqueness_cache_data']['lid'])
40
+ end
41
+
42
+ it "unlocks after rescheduling" do
43
+ TestWorker.clear
44
+ TestWorker.unique_job_options.merge!({ strategy: :while_executing, on_conflict: :reschedule })
45
+
46
+ lock_context.handle_lifecycle!(:enqueue) {}
47
+ lock_context.handle_lifecycle!(:perform) {}
48
+
49
+ TestWorker.perform_async
50
+ expect(TestWorker.jobs.size).to eq(1)
51
+ TestWorker.perform_one
52
+ expect(TestWorker.jobs.size).to eq(1)
53
+
54
+ lock_context.lock_strategy.send(:unlock)
55
+ Sidekiq::Worker.drain_all
56
+ expect(TestWorker.jobs.size).to eq(0)
57
+
58
+ # Run another worker to validate that the lock was released
59
+ TestWorker.perform_async
60
+ TestWorker.perform_one
61
+ expect(TestWorker.jobs.size).to eq(0)
62
+ end
24
63
  end
@@ -7,7 +7,7 @@ Redis.silence_deprecations = true
7
7
  Dir[File.join(File.dirname(__FILE__), "./support/**/*.rb")].sort.each { |f| require f }
8
8
 
9
9
  Sidekiq::Testing.server_middleware do |chain|
10
- chain.insert_before CanvasSync::JobBatches::Compat::Sidekiq::ServerMiddleware, CanvasSync::JobUniqueness::Compat::Sidekiq::ServerMiddleware
10
+ chain.insert_after CanvasSync::JobBatches::Compat::Sidekiq::ServerMiddleware, CanvasSync::JobUniqueness::Compat::Sidekiq::ServerMiddleware
11
11
  end
12
12
 
13
13
  RSpec.configure do |config|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.0.beta8
4
+ version: 0.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure CustomDev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-25 00:00:00.000000000 Z
11
+ date: 2024-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -870,9 +870,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
870
870
  version: '0'
871
871
  required_rubygems_version: !ruby/object:Gem::Requirement
872
872
  requirements:
873
- - - ">"
873
+ - - ">="
874
874
  - !ruby/object:Gem::Version
875
- version: 1.3.1
875
+ version: '0'
876
876
  requirements: []
877
877
  rubygems_version: 3.1.6
878
878
  signing_key: