canvas_sync 0.17.35 → 0.17.37

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: 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