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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43e293e4d64336d70983fbf6eedffb1279252c7d95dfe7a525aa1fa2da5f5463
4
- data.tar.gz: b13c557e206b4ea989ff962ad385b0fef0862e67a07626eb8a661faae8c96fd2
3
+ metadata.gz: aa91c7ca59af567024be0ac8cb9d13ffff059fe7c04fb075101609b3fc78fe4f
4
+ data.tar.gz: 8f4e9744ed47825c119e4725c506bf8a55a0dca44d045f49c239e272eed3ea7d
5
5
  SHA512:
6
- metadata.gz: 1866a0aafdc8eac4471c5e498055a64690f99982218d06a0ea14ac5ad8a496df1db6add14012d967a8de61efcdced32a1ec14aa7d5dc07c2a0299dc837cd6f0e
7
- data.tar.gz: e16462ec03aa1a207871ab2dee9d0075a349aa09aaa7c8014833e9c4f3abe684a62e124fbdc5a76bd5340b913add521ec4304eae0f449b95c624358c4504c8f3
6
+ metadata.gz: 9a6213cb2348019af23683bfa1847e6f0025dd81269fe0950f6a0217acd15565d74096cbcc536bdd42eea8d214f1a5e8a67f8fd6f5188a09aa5442d8f7a26ac7
7
+ data.tar.gz: 8a502df328aff5498bf191bc6b3ef73ed91c32b1bcdf2b0f9aa1ec14ce8f0aaf9c908284c8e51da61b2ce51c97df43af0461c297dcb1b0b48252aab8b0240cad
@@ -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.smembers(key, 0, -1)
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"]}, callback batch id: #{callback_bid} callback_batch #{is_callback_batch}"}
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)
@@ -1,6 +1,6 @@
1
1
  module CanvasSync
2
2
  module JobBatches
3
- class BaseJob < ActiveJob::Base
3
+ class BaseJob < ::ActiveJob::Base
4
4
 
5
5
  end
6
6
  end
@@ -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 msg['class'] == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' && (msg['wrapped'].to_s).constantize < BatchAwareJob
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
- return unless job['bid'].present?
102
-
103
- if defined?(::Apartment)
104
- ::Apartment::Tenant.switch(job['apartment'] || 'public') do
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
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.17.35".freeze
2
+ VERSION = "0.17.37".freeze
3
3
  end