canvas_sync 0.17.24 → 0.17.26.beta1

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: ff1d01575608d114952bb12803cae01cc2f4ff61c8ffeed78f18b247973926fa
4
- data.tar.gz: ba3629041f491bb7bac12e03da3c896563c9595c77b58cec0d0c728f97168fcf
3
+ metadata.gz: ce544260a5cc94f9193cb99da3bc55e06ecd1078e0ef6a5afca282cc4d39169f
4
+ data.tar.gz: 30a5bccedebde1cb00aeb31219b1d9f605672fa8ea58cb50af483cf8f98d15fb
5
5
  SHA512:
6
- metadata.gz: 73ef3c21b2bb55276da6d5bd96a13b089117e47a04a117d4533822dc790eb2a62b2f8ac88fbfe122a4292e801542c49facef12554fd9a7c80426f699125d42b2
7
- data.tar.gz: 29be22e24cb562c9decae8986b5e8a2b7f09da39a80e019edfe6f3cc994a90a2d53da1c9bae4e3d56640d630d7fbd8abca43e8bf946d35c211dae0a00833ef91
6
+ metadata.gz: e84bde52492c2276650bd662adff677c0aa6a1c511587886d45fc6d328389af242ade72fe872dda2093df9ebb151aa25a4a353559a31d74330849f0a0c93d159
7
+ data.tar.gz: 3c30eceedad806932b61abc66456973250c7247ba7431406f1c5440b09b05cc3b7174112e34e78392d8f3e9c89dfcd7eba43377a0f8ee30d6320a00a50303163
@@ -37,16 +37,29 @@ module CanvasSync
37
37
  insert_at(-1, new_job)
38
38
  end
39
39
 
40
- def insert_at(position, new_jobs)
40
+ def insert_at(position, new_jobs, *args, &blk)
41
41
  chain = self.class.get_chain_parameter(base_job)
42
+ if new_jobs.is_a?(Class) || new_jobs.is_a?(String)
43
+ new_jobs = build_job_hash(new_jobs, *args, &blk)
44
+ elsif args.length > 0
45
+ raise "Unexpected number of arguments"
46
+ end
42
47
  new_jobs = [new_jobs] unless new_jobs.is_a?(Array)
43
48
  chain.insert(position, *new_jobs)
44
49
  end
45
50
 
46
- def insert(new_jobs, **kwargs)
47
- invalid_params = kwargs.keys - VALID_PLACEMENT_PARAMETERS
48
- raise "Invalid placement parameters: #{invalid_params.map(&:to_s).join(', ')}" if invalid_params.present?
49
- raise "At most one placement parameter may be provided" if kwargs.values.compact.length > 1
51
+ def insert(new_jobs, *args, **kwargs, &blk)
52
+ if new_jobs.is_a?(Class) || new_jobs.is_a?(String)
53
+ job_kwargs = kwargs.except(*VALID_PLACEMENT_PARAMETERS)
54
+ args << job_kwargs if job_kwargs.present?
55
+ new_jobs = build_job_hash(new_jobs, *args, &blk)
56
+ kwargs = kwargs.slice(*VALID_PLACEMENT_PARAMETERS)
57
+ else
58
+ invalid_params = kwargs.keys - VALID_PLACEMENT_PARAMETERS
59
+ raise "Invalid placement parameters: #{invalid_params.map(&:to_s).join(', ')}" if invalid_params.present?
60
+ raise "At most one placement parameter may be provided" if kwargs.values.compact.length > 1
61
+ raise "Unexpected number of arguments" if args.length > 0
62
+ end
50
63
 
51
64
  new_jobs = [new_jobs] unless new_jobs.is_a?(Array)
52
65
 
@@ -90,7 +103,6 @@ module CanvasSync
90
103
  raise "Found multiple \"#{sub_type}\" jobs in the chain" if matching_jobs.count > 1
91
104
  return nil if matching_jobs.count == 0
92
105
 
93
-
94
106
  job = matching_jobs[0][0]
95
107
  job = self.class.new(job) unless job.is_a?(ChainBuilder)
96
108
  job
@@ -116,8 +128,22 @@ module CanvasSync
116
128
  end
117
129
  end
118
130
 
131
+ def apply_block(&blk)
132
+ return unless blk.present?
133
+ instance_exec(&blk)
134
+ end
135
+
119
136
  private
120
137
 
138
+ def build_job_hash(job, *params, &blk)
139
+ hsh = {
140
+ job: job,
141
+ parameters: params,
142
+ }
143
+ self.class.new(hsh).apply_block(&blk) if blk.present?
144
+ hsh
145
+ end
146
+
121
147
  def find_matching_jobs(search_job, parent_job = self.base_job)
122
148
  return to_enum(:find_matching_jobs, search_job, parent_job) unless block_given?
123
149
 
@@ -150,6 +176,13 @@ module CanvasSync
150
176
  end
151
177
 
152
178
  class << self
179
+ def build(job, *args, &blk)
180
+ new(job).tap do |ch|
181
+ ch[:parameters] = args
182
+ ch.apply_block(&blk)
183
+ end
184
+ end
185
+
153
186
  def _job_type_definitions
154
187
  @job_type_definitions ||= {}
155
188
  end
@@ -14,6 +14,12 @@ module CanvasSync
14
14
  globals[:updated_after] = last_batch&.started_at&.iso8601
15
15
  end
16
16
 
17
+ # Refuse to run syncs of the same genre if there is a running full sync
18
+ if last_full_sync_record&.status == 'processing' && last_full_sync > 12.hours.ago
19
+ Rails.logger.warn("Attempted to start a '#{genre}' sync while a full-sync is still processing.")
20
+ return
21
+ end
22
+
17
23
  if should_full_sync?(globals[:full_sync_every])
18
24
  globals[:updated_after] = nil
19
25
  end
@@ -25,6 +31,8 @@ module CanvasSync
25
31
  status: 'processing',
26
32
  )
27
33
 
34
+ globals[:sync_batch_id] = sync_batch.id
35
+
28
36
  JobBatches::Batch.new.tap do |b|
29
37
  b.description = "CanvasSync Root Batch (SyncBatch##{sync_batch.id})"
30
38
  b.on(:complete, "#{self.class.to_s}.batch_completed", sync_batch_id: sync_batch.id)
@@ -62,7 +70,7 @@ module CanvasSync
62
70
  end
63
71
 
64
72
  def last_full_sync_record
65
- @last_full_sync_record ||= SyncBatch.where(status: 'completed', full_sync: true, batch_genre: genre).last
73
+ @last_full_sync_record ||= SyncBatch.where(status: ['completed', 'processing'], full_sync: true, batch_genre: genre).last
66
74
  end
67
75
 
68
76
  def last_full_sync
@@ -23,23 +23,7 @@ module CanvasSync
23
23
  end
24
24
  end
25
25
 
26
- if (jobs = options[:sub_jobs]).present?
27
- context = options[:context] || {}
28
- if options[:term_scope]
29
- Term.send(options[:term_scope]).find_each.map do |term|
30
- local_context = context.merge(canvas_term_id: get_term_id(term))
31
- JobBatches::ConcurrentBatchJob.perform_now(jobs, context: local_context)
32
- end
33
- else
34
- JobBatches::ConcurrentBatchJob.perform_now(jobs, context: context)
35
- end
36
- end
37
- end
38
-
39
- protected
40
-
41
- def get_term_id(term)
42
- term.try(:canvas_id) || term.canvas_term_id
26
+ TermBatchesJob.perform_now(options)
43
27
  end
44
28
  end
45
29
  end
@@ -0,0 +1,23 @@
1
+ module CanvasSync
2
+ module Jobs
3
+ class TermBatchesJob < CanvasSync::Job
4
+ def perform(options)
5
+ if (jobs = options[:sub_jobs]).present?
6
+ context = options[:context] || {}
7
+ if options[:term_scope]
8
+ Term.send(options[:term_scope]).find_each.map do |term|
9
+ local_context = context.merge(canvas_term_id: get_term_id(term))
10
+ JobBatches::ConcurrentBatchJob.perform_now(jobs, context: local_context)
11
+ end
12
+ else
13
+ JobBatches::ConcurrentBatchJob.perform_now(jobs, context: context)
14
+ end
15
+ end
16
+ end
17
+
18
+ def get_term_id(term)
19
+ term.try(:canvas_id) || term.canvas_term_id
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module CanvasSync
2
- VERSION = "0.17.24".freeze
2
+ VERSION = "0.17.26.beta1".freeze
3
3
  end
data/lib/canvas_sync.rb CHANGED
@@ -80,6 +80,7 @@ module CanvasSync
80
80
  ].freeze
81
81
 
82
82
  JobBatches::ChainBuilder.register_chain_job(CanvasSync::Jobs::SyncTermsJob, :sub_jobs)
83
+ JobBatches::ChainBuilder.register_chain_job(CanvasSync::Jobs::TermBatchesJob, :sub_jobs)
83
84
  JobBatches::ChainBuilder.register_chain_job(CanvasSync::Jobs::BeginSyncChainJob, 0)
84
85
 
85
86
  class << self
@@ -130,12 +131,8 @@ module CanvasSync
130
131
  models,
131
132
  term_scope: nil,
132
133
  term_scoped_models: DEFAULT_TERM_SCOPE_MODELS,
133
- legacy_support: false,
134
- account_id: nil,
135
- updated_after: nil,
136
- full_sync_every: nil,
137
- batch_genre: nil,
138
- options: {}
134
+ options: {},
135
+ **kwargs
139
136
  ) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/LineLength
140
137
  return unless models.present?
141
138
  models.map! &:to_s
@@ -155,7 +152,7 @@ module CanvasSync
155
152
  context_module_items: CanvasSync::Jobs::SyncContextModuleItemsJob,
156
153
  }.with_indifferent_access
157
154
 
158
- root_chain = JobBatches::ChainBuilder.new(CanvasSync::Jobs::BeginSyncChainJob)
155
+ root_chain = base_canvas_sync_chain(**kwargs, globals: options[:global] || kwargs[:globals])
159
156
  concurrent_root_chain = JobBatches::ChainBuilder.new(JobBatches::ConcurrentBatchJob)
160
157
  root_chain << concurrent_root_chain
161
158
  current_chain = concurrent_root_chain
@@ -211,6 +208,20 @@ module CanvasSync
211
208
  # Wrap it all up
212
209
  ###############################
213
210
 
211
+ root_chain
212
+ end
213
+
214
+ def base_canvas_sync_chain(
215
+ legacy_support: false, # Import records 1 by 1 instead of with bulk upserts
216
+ account_id: nil, # legacy/non PandaPal apps
217
+ updated_after: nil,
218
+ full_sync_every: nil,
219
+ batch_genre: nil,
220
+ globals: {},
221
+ &blk
222
+ )
223
+ root_chain = JobBatches::ChainBuilder.new(CanvasSync::Jobs::BeginSyncChainJob)
224
+
214
225
  global_options = {
215
226
  legacy_support: legacy_support,
216
227
  updated_after: updated_after,
@@ -218,10 +229,12 @@ module CanvasSync
218
229
  batch_genre: batch_genre,
219
230
  }
220
231
  global_options[:account_id] = account_id if account_id.present?
221
- global_options.merge!(options[:global]) if options[:global].present?
232
+ global_options.merge!(globals) if globals
222
233
 
223
234
  root_chain.params[1] = global_options
224
235
 
236
+ root_chain.apply_block(&blk)
237
+
225
238
  root_chain
226
239
  end
227
240
 
@@ -35,11 +35,18 @@ RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
35
35
  end
36
36
 
37
37
  it 'processes xlist' do
38
+ subject.process('spec/support/fixtures/reports/sections.csv', { models: ['sections'] }, 1)
39
+ expect(Section.find_by(canvas_id: 2).name).to eq "Lame Section"
40
+
38
41
  subject.process('spec/support/fixtures/reports/xlist.csv', { models: ['xlist'] }, 1)
42
+
39
43
  expect(Section.where.not(canvas_nonxlist_course_id: nil).count).to eq 1
40
44
  cross_listed_section = Section.where.not(canvas_nonxlist_course_id: nil).first
41
45
  expect(cross_listed_section.canvas_id).to eq 2
42
- expect(cross_listed_section.canvas_nonxlist_course_id).to eq 2
46
+ expect(cross_listed_section.canvas_nonxlist_course_id).to eq 3
47
+
48
+ expect(cross_listed_section.canvas_course_id).to eq 2
49
+ expect(cross_listed_section.name).to eq "Lame Section"
43
50
  end
44
51
 
45
52
  it 'processes groups' do