canvas_sync 0.22.0.beta8 → 0.22.1
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/lib/canvas_sync/job_batches/compat/sidekiq.rb +1 -1
- data/lib/canvas_sync/job_uniqueness/compat/active_job.rb +1 -1
- data/lib/canvas_sync/job_uniqueness/compat/sidekiq.rb +2 -2
- data/lib/canvas_sync/job_uniqueness/lock_context.rb +2 -2
- data/lib/canvas_sync/job_uniqueness/locksmith.rb +1 -3
- data/lib/canvas_sync/job_uniqueness/strategy/base.rb +1 -6
- data/lib/canvas_sync/jobs/canvas_process_waiter.rb +1 -1
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/job_batching/compat/sidekiq_spec.rb +1 -1
- data/spec/job_uniqueness/on_conflict/reschedule_spec.rb +39 -0
- data/spec/job_uniqueness/spec_helper.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d55ef789158e71984651c554186f25c0206632712483cb1f196f0f772183641f
|
4
|
+
data.tar.gz: e88f323145871f95d6979bd4c089fd9c993a5118e2075feb0e96257b96dad8ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34e5d02b710c1252657dd7d675b85d085a69bc6c03b0e52285f7264f5c7f5119113c6164bb148979eabf8a1c24be6f1f781ff28b61f9faf0aed331321369e598
|
7
|
+
data.tar.gz: 74f7b996899e7e4d45f74f04aabf2d098f0531c0bbae5594cfbc604661d0762aa765a9ea4d94358ebc40cbbfaeef1dfb5219c4ab8eb2be50cd3044290b7139e9
|
@@ -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[
|
48
|
+
batch.increment_job_queue(msg['jid']) if (msg['bid'] = batch.bid)
|
49
49
|
end
|
50
50
|
yield
|
51
51
|
end
|
@@ -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
|
-
|
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
|
@@ -9,7 +9,7 @@ module CanvasSync::Jobs
|
|
9
9
|
|
10
10
|
if %w[completed complete imported imported_with_messages].include? status
|
11
11
|
InvokeCallbackWorker.perform_later(build_next_job(next_job, kwargs, response)) if next_job
|
12
|
-
elsif %w[failed error failed_with_messages].include? status
|
12
|
+
elsif %w[failed error failed_with_messages imports_failed exports_failed].include? status
|
13
13
|
if kwargs[:on_failure].is_a?(Hash)
|
14
14
|
InvokeCallbackWorker.perform_later(build_next_job(kwargs[:on_failure], kwargs, response))
|
15
15
|
else
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -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.
|
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.
|
4
|
+
version: 0.22.1
|
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-
|
11
|
+
date: 2024-08-12 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:
|
875
|
+
version: '0'
|
876
876
|
requirements: []
|
877
877
|
rubygems_version: 3.1.6
|
878
878
|
signing_key:
|