canvas_sync 0.17.35 → 0.17.37
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/engine.rb +6 -0
- data/lib/canvas_sync/job_batches/active_job.rb +108 -0
- data/lib/canvas_sync/job_batches/batch.rb +7 -4
- data/lib/canvas_sync/job_batches/callback.rb +1 -13
- data/lib/canvas_sync/job_batches/jobs/base_job.rb +1 -1
- data/lib/canvas_sync/job_batches/jobs/managed_batch_job.rb +2 -2
- data/lib/canvas_sync/job_batches/pool.rb +2 -2
- data/lib/canvas_sync/job_batches/sidekiq.rb +21 -7
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/dummy/log/test.log +23910 -0
- data/spec/job_batching/active_job_spec.rb +107 -0
- data/spec/job_batching/batch_spec.rb +1 -1
- metadata +5 -5
- data/lib/canvas_sync/job_batches/batch_aware_job.rb +0 -63
- data/spec/job_batching/batch_aware_job_spec.rb +0 -101
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa91c7ca59af567024be0ac8cb9d13ffff059fe7c04fb075101609b3fc78fe4f
|
4
|
+
data.tar.gz: 8f4e9744ed47825c119e4725c506bf8a55a0dca44d045f49c239e272eed3ea7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a6213cb2348019af23683bfa1847e6f0025dd81269fe0950f6a0217acd15565d74096cbcc536bdd42eea8d214f1a5e8a67f8fd6f5188a09aa5442d8f7a26ac7
|
7
|
+
data.tar.gz: 8a502df328aff5498bf191bc6b3ef73ed91c32b1bcdf2b0f9aa1ec14ce8f0aaf9c908284c8e51da61b2ce51c97df43af0461c297dcb1b0b48252aab8b0240cad
|
data/lib/canvas_sync/engine.rb
CHANGED
@@ -5,6 +5,12 @@ module CanvasSync
|
|
5
5
|
class Engine < ::Rails::Engine
|
6
6
|
isolate_namespace CanvasSync
|
7
7
|
|
8
|
+
initializer "canvas_sync.serialze_symbols" do |app|
|
9
|
+
app.config.active_record.yaml_column_permitted_classes ||= []
|
10
|
+
app.config.active_record.yaml_column_permitted_classes |= [Symbol]
|
11
|
+
rescue
|
12
|
+
end
|
13
|
+
|
8
14
|
initializer :append_migrations do |app|
|
9
15
|
config.paths["db/migrate"].expanded.each do |expanded_path|
|
10
16
|
app.config.paths["db/migrate"] << expanded_path
|
@@ -0,0 +1,108 @@
|
|
1
|
+
|
2
|
+
module CanvasSync
|
3
|
+
module JobBatches
|
4
|
+
module ActiveJob
|
5
|
+
module BatchAwareJob
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
around_perform do |job, block|
|
10
|
+
if (@bid) # This _must_ be @bid - not just bid
|
11
|
+
prev_batch = Thread.current[CURRENT_BATCH_THREAD_KEY]
|
12
|
+
begin
|
13
|
+
Thread.current[CURRENT_BATCH_THREAD_KEY] = Batch.new(@bid)
|
14
|
+
block.call
|
15
|
+
Thread.current[CURRENT_BATCH_THREAD_KEY].save_context_changes
|
16
|
+
Batch.process_successful_job(@bid, job_id)
|
17
|
+
rescue
|
18
|
+
Batch.process_failed_job(@bid, job_id)
|
19
|
+
raise
|
20
|
+
ensure
|
21
|
+
Thread.current[CURRENT_BATCH_THREAD_KEY] = prev_batch
|
22
|
+
end
|
23
|
+
else
|
24
|
+
block.call
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
around_enqueue do |job, block|
|
29
|
+
if (batch = Thread.current[CURRENT_BATCH_THREAD_KEY])
|
30
|
+
@bid = batch.bid
|
31
|
+
batch.increment_job_queue(job_id) if @bid
|
32
|
+
end
|
33
|
+
block.call
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def bid
|
38
|
+
@bid || Thread.current[CURRENT_BATCH_THREAD_KEY]&.bid
|
39
|
+
end
|
40
|
+
|
41
|
+
def batch
|
42
|
+
Thread.current[CURRENT_BATCH_THREAD_KEY]
|
43
|
+
end
|
44
|
+
|
45
|
+
def batch_context
|
46
|
+
batch&.context || {}
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid_within_batch?
|
50
|
+
batch.valid?
|
51
|
+
end
|
52
|
+
|
53
|
+
def serialize
|
54
|
+
super.tap do |data|
|
55
|
+
data['batch_id'] = @bid # This _must_ be @bid - not just bid
|
56
|
+
data
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def deserialize(data)
|
61
|
+
super
|
62
|
+
@bid = data['batch_id']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ActiveJobCallbackWorker < ::ActiveJob::Base
|
67
|
+
include Batch::Callback::CallbackWorkerCommon
|
68
|
+
|
69
|
+
def self.enqueue_all(args, queue)
|
70
|
+
args.each do |arg_set|
|
71
|
+
set(queue: queue).perform_later(*arg_set)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.handle_job_death(job, error = nil)
|
77
|
+
if job.is_a?(Array)
|
78
|
+
event = ActiveSupport::Notifications::Event.new(*job)
|
79
|
+
payload = event.payload
|
80
|
+
job = payload[:job].serialize
|
81
|
+
error = payload[:error]
|
82
|
+
end
|
83
|
+
|
84
|
+
if job["job_id"].present? && job["batch_id"].present?
|
85
|
+
CanvasSync::JobBatches::Batch.process_dead_job(job['batch_id'], job['job_id'])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.configure
|
90
|
+
::ActiveJob::Base.include BatchAwareJob
|
91
|
+
|
92
|
+
begin
|
93
|
+
ActiveSupport::Notifications.subscribe "discard.active_job" do |*args|
|
94
|
+
handle_job_death(args)
|
95
|
+
end
|
96
|
+
|
97
|
+
ActiveSupport::Notifications.subscribe "retry_stopped.active_job" do |*args|
|
98
|
+
handle_job_death(args)
|
99
|
+
end
|
100
|
+
rescue => err
|
101
|
+
Rails.logger.warn(err)
|
102
|
+
end
|
103
|
+
|
104
|
+
Batch::Callback.worker_class ||= ActiveJobCallbackWorker
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -6,7 +6,6 @@ end
|
|
6
6
|
|
7
7
|
require_relative './redis_model'
|
8
8
|
require_relative './redis_script'
|
9
|
-
require_relative './batch_aware_job'
|
10
9
|
require_relative "./callback"
|
11
10
|
require_relative "./context_hash"
|
12
11
|
require_relative "./status"
|
@@ -465,7 +464,7 @@ module CanvasSync
|
|
465
464
|
when 'set'
|
466
465
|
r.smembers(key)
|
467
466
|
when 'zset'
|
468
|
-
r.
|
467
|
+
r.zrange(key, 0, -1)
|
469
468
|
end
|
470
469
|
end
|
471
470
|
end
|
@@ -481,8 +480,6 @@ module CanvasSync
|
|
481
480
|
end
|
482
481
|
end
|
483
482
|
end
|
484
|
-
|
485
|
-
ActiveJob::Base.include BatchAwareJob
|
486
483
|
end
|
487
484
|
end
|
488
485
|
|
@@ -491,3 +488,9 @@ if defined?(::Sidekiq)
|
|
491
488
|
require_relative './sidekiq'
|
492
489
|
CanvasSync::JobBatches::Sidekiq.configure
|
493
490
|
end
|
491
|
+
|
492
|
+
# Automatically integrate with ActiveJob if it is present.
|
493
|
+
if defined?(::ActiveJob)
|
494
|
+
require_relative './active_job'
|
495
|
+
CanvasSync::JobBatches::ActiveJob.configure
|
496
|
+
end
|
@@ -38,24 +38,12 @@ module CanvasSync
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
class ActiveJobCallbackWorker < ActiveJob::Base
|
42
|
-
include CallbackWorkerCommon
|
43
|
-
|
44
|
-
def self.enqueue_all(args, queue)
|
45
|
-
args.each do |arg_set|
|
46
|
-
set(queue: queue).perform_later(*arg_set)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
worker_class = ActiveJobCallbackWorker
|
52
|
-
|
53
41
|
class Finalize
|
54
42
|
def dispatch(status, opts)
|
55
43
|
bid = opts["bid"]
|
56
44
|
event = opts["event"].to_sym
|
57
45
|
|
58
|
-
Batch.logger.debug {"Finalize #{event} batch id: #{opts["bid"]}
|
46
|
+
Batch.logger.debug {"Finalize #{event} batch id: #{opts["bid"]}"}
|
59
47
|
|
60
48
|
batch_status = Status.new bid
|
61
49
|
send(event, bid, batch_status, batch_status.parent_bid)
|
@@ -26,7 +26,7 @@ module CanvasSync
|
|
26
26
|
|
27
27
|
mapped_sub_jobs = sub_jobs.each_with_index.map do |j, i|
|
28
28
|
j['_mngbid_index_'] = i # This allows duplicate jobs when a Redis Set is used
|
29
|
-
j = ActiveJob::Arguments.serialize([j])
|
29
|
+
j = ::ActiveJob::Arguments.serialize([j])
|
30
30
|
JSON.unparse(j)
|
31
31
|
end
|
32
32
|
if ordered
|
@@ -104,7 +104,7 @@ module CanvasSync
|
|
104
104
|
return unless next_job_json.present?
|
105
105
|
|
106
106
|
next_job = JSON.parse(next_job_json)
|
107
|
-
next_job = ActiveJob::Arguments.deserialize(next_job)[0]
|
107
|
+
next_job = ::ActiveJob::Arguments.deserialize(next_job)[0]
|
108
108
|
|
109
109
|
Batch.new(root_bid).jobs do
|
110
110
|
Batch.new.tap do |batch|
|
@@ -171,7 +171,7 @@ module CanvasSync
|
|
171
171
|
jobs_key = "#{redis_key}-jobs"
|
172
172
|
# This allows duplicate jobs when a Redis Set is used
|
173
173
|
job_desc[:_pool_random_key_] = SecureRandom.urlsafe_base64(10)
|
174
|
-
job_json = JSON.unparse(ActiveJob::Arguments.serialize([job_desc]))
|
174
|
+
job_json = JSON.unparse(::ActiveJob::Arguments.serialize([job_desc]))
|
175
175
|
order = self.order
|
176
176
|
|
177
177
|
redis.multi do |r|
|
@@ -204,7 +204,7 @@ module CanvasSync
|
|
204
204
|
|
205
205
|
return nil unless job_json.present?
|
206
206
|
|
207
|
-
ActiveJob::Arguments.deserialize(JSON.parse(job_json))[0]&.symbolize_keys
|
207
|
+
::ActiveJob::Arguments.deserialize(JSON.parse(job_json))[0]&.symbolize_keys
|
208
208
|
end
|
209
209
|
|
210
210
|
def self.redis(&blk)
|
@@ -49,7 +49,7 @@ module CanvasSync
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def should_handle_batch?(msg)
|
52
|
-
return false if
|
52
|
+
return false if JobBatches::Sidekiq.is_activejob_job?(msg)
|
53
53
|
true
|
54
54
|
end
|
55
55
|
end
|
@@ -75,6 +75,22 @@ module CanvasSync
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
def self.is_activejob_job?(msg)
|
79
|
+
return false unless defined?(::ActiveJob)
|
80
|
+
|
81
|
+
msg['class'] == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' && (msg['wrapped'].to_s).constantize < JobBatches::ActiveJob::BatchAwareJob
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.switch_tenant(job)
|
85
|
+
if defined?(::Apartment)
|
86
|
+
::Apartment::Tenant.switch(job['apartment'] || 'public') do
|
87
|
+
yield
|
88
|
+
end
|
89
|
+
else
|
90
|
+
yield
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
78
94
|
def self.configure
|
79
95
|
if defined?(::Sidekiq::Batch) && ::Sidekiq::Batch != JobBatches::Batch
|
80
96
|
print "WARNING: Detected Sidekiq Pro or sidekiq-batch. CanvasSync JobBatches may not be fully compatible!"
|
@@ -98,14 +114,12 @@ module CanvasSync
|
|
98
114
|
end
|
99
115
|
|
100
116
|
config.death_handlers << ->(job, ex) do
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
117
|
+
switch_tenant(job) do
|
118
|
+
if is_activejob_job?(job)
|
119
|
+
JobBatches::ActiveJob.handle_job_death(job["args"][0], ex)
|
120
|
+
elsif job['bid'].present?
|
105
121
|
::Sidekiq::Batch.process_dead_job(job['bid'], job['jid'])
|
106
122
|
end
|
107
|
-
else
|
108
|
-
::Sidekiq::Batch.process_dead_job(job['bid'], job['jid'])
|
109
123
|
end
|
110
124
|
end
|
111
125
|
end
|
data/lib/canvas_sync/version.rb
CHANGED