canvas_sync 0.17.17.beta1 → 0.17.23.beta1
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/README.md +45 -1
- data/lib/canvas_sync/concerns/sync_mapping.rb +112 -0
- data/lib/canvas_sync/generators/install_generator.rb +1 -0
- data/lib/canvas_sync/generators/templates/migrations/create_grading_period_groups.rb +22 -0
- data/lib/canvas_sync/generators/templates/migrations/create_grading_periods.rb +22 -0
- data/lib/canvas_sync/generators/templates/migrations/create_user_observers.rb +17 -0
- data/lib/canvas_sync/generators/templates/models/grading_period.rb +8 -0
- data/lib/canvas_sync/generators/templates/models/grading_period_group.rb +9 -0
- data/lib/canvas_sync/generators/templates/models/user_observer.rb +11 -0
- data/lib/canvas_sync/importers/bulk_importer.rb +27 -16
- data/lib/canvas_sync/job_batches/batch.rb +9 -0
- data/lib/canvas_sync/job_batches/chain_builder.rb +9 -1
- data/lib/canvas_sync/job_batches/hier_batch_ids.lua +25 -0
- data/lib/canvas_sync/job_batches/sidekiq/web/batches_assets/css/styles.less +178 -0
- data/lib/canvas_sync/job_batches/sidekiq/web/batches_assets/js/batch_tree.js +106 -0
- data/lib/canvas_sync/job_batches/sidekiq/web/batches_assets/js/util.js +2 -0
- data/lib/canvas_sync/job_batches/sidekiq/web/views/_batch_tree.erb +6 -0
- data/lib/canvas_sync/job_batches/sidekiq/web/views/_common.erb +13 -0
- data/lib/canvas_sync/job_batches/sidekiq/web/views/batch.erb +15 -88
- data/lib/canvas_sync/job_batches/sidekiq/web.rb +93 -0
- data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +1 -1
- data/lib/canvas_sync/jobs/report_checker.rb +37 -4
- data/lib/canvas_sync/jobs/report_starter.rb +2 -2
- data/lib/canvas_sync/processors/assignment_groups_processor.rb +1 -7
- data/lib/canvas_sync/processors/assignments_processor.rb +1 -7
- data/lib/canvas_sync/processors/context_module_items_processor.rb +1 -7
- data/lib/canvas_sync/processors/context_modules_processor.rb +1 -7
- data/lib/canvas_sync/processors/model_mappings.yml +68 -0
- data/lib/canvas_sync/processors/normal_processor.rb +3 -3
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +21 -63
- data/lib/canvas_sync/processors/report_processor.rb +14 -9
- data/lib/canvas_sync/processors/submissions_processor.rb +1 -7
- data/lib/canvas_sync/record.rb +4 -0
- data/lib/canvas_sync/version.rb +1 -1
- data/lib/canvas_sync.rb +4 -1
- data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +40 -0
- data/spec/dummy/app/models/grading_period.rb +14 -0
- data/spec/dummy/app/models/grading_period_group.rb +15 -0
- data/spec/dummy/app/models/user_observer.rb +17 -0
- data/spec/dummy/db/migrate/20210907233329_create_user_observers.rb +23 -0
- data/spec/dummy/db/migrate/20210907233330_create_grading_periods.rb +28 -0
- data/spec/dummy/db/migrate/20210907233331_create_grading_period_groups.rb +28 -0
- data/spec/dummy/db/schema.rb +42 -1
- data/spec/dummy/log/development.log +1167 -0
- data/spec/dummy/log/test.log +2775 -0
- data/spec/support/fixtures/reports/grading_period_groups.csv +2 -0
- data/spec/support/fixtures/reports/grading_periods.csv +3 -0
- data/spec/support/fixtures/reports/user_observers.csv +3 -0
- metadata +38 -17
@@ -0,0 +1,106 @@
|
|
1
|
+
import { h, Component, render } from 'https://unpkg.com/preact?module';
|
2
|
+
import htm from 'https://unpkg.com/htm?module';
|
3
|
+
import { root_url } from './util.js';
|
4
|
+
|
5
|
+
// Initialize htm with Preact
|
6
|
+
const html = htm.bind(h);
|
7
|
+
|
8
|
+
const StatusBlock = (props) => html`
|
9
|
+
<div class="status-block ${props.class || ''}">
|
10
|
+
${props.title && props.title + ':'}
|
11
|
+
<span class="tree-stat pending">${props.pending_count}</span>
|
12
|
+
|
|
13
|
+
<span class="tree-stat failed">${props.failed_count}</span>
|
14
|
+
|
|
15
|
+
<span class="tree-stat success">${props.successful_count}</span>
|
16
|
+
/
|
17
|
+
<span class="tree-stat total">${props.total_count}</span>
|
18
|
+
</div>
|
19
|
+
`
|
20
|
+
|
21
|
+
class TreeLevel extends Component {
|
22
|
+
get bid() {
|
23
|
+
return this.props.data.bid;
|
24
|
+
}
|
25
|
+
|
26
|
+
get batch() {
|
27
|
+
return this.props.data;
|
28
|
+
}
|
29
|
+
|
30
|
+
load_more = async (event) => {
|
31
|
+
event.preventDefault();
|
32
|
+
const l = this.batch.batches.items.length;
|
33
|
+
const resp = await fetch(`${root_url}batches/${this.bid}/tree?slice=${l}:${l + 5 - 1}`)
|
34
|
+
const result = await resp.json()
|
35
|
+
const newEntries = result.batches.items;
|
36
|
+
for (let ent of newEntries) {
|
37
|
+
this.batch.batches.items.push(ent)
|
38
|
+
}
|
39
|
+
this.forceUpdate()
|
40
|
+
}
|
41
|
+
|
42
|
+
toggle = (event) => {
|
43
|
+
event.preventDefault();
|
44
|
+
this.setState({ collapsed: !this.state.collapsed })
|
45
|
+
}
|
46
|
+
|
47
|
+
render() {
|
48
|
+
const { data: bd } = this.props;
|
49
|
+
|
50
|
+
let sub_entries = [];
|
51
|
+
let sub_batches = bd.batches.items;
|
52
|
+
for (let b of sub_batches) {
|
53
|
+
sub_entries.push(html`<${TreeLevel} data=${b} />`)
|
54
|
+
}
|
55
|
+
|
56
|
+
let fully_loaded = !(sub_batches.length < bd.batches.total_count);
|
57
|
+
|
58
|
+
const load_more_elem = html`<div class="load-more">
|
59
|
+
${sub_entries.length} / ${bd.batches.total_count} Items Loaded - <a href="#" onClick=${this.load_more}>Load More</a>
|
60
|
+
</div>`
|
61
|
+
|
62
|
+
return html`<div class="tree-entry tree-batch">
|
63
|
+
<div class="header">
|
64
|
+
<a class="row-toggle ${!bd.batches.total_count && 'not_applicable'}" onClick=${this.toggle} href="#">
|
65
|
+
${this.state.collapsed ? '+' : '-'}
|
66
|
+
</a>
|
67
|
+
|
68
|
+
<div class="header-inner">
|
69
|
+
<div class="main">
|
70
|
+
<span class="bid">
|
71
|
+
${bd.bid}
|
72
|
+
<a class="bid-goto" href="${root_url}batches/${bd.bid}">⇢</a>
|
73
|
+
</span>
|
74
|
+
${bd.description || (bd.status == 'deleted' && html`<i class="text-inactive">Deleted</i>`) || html`<i class="text-inactive">No Description</i>`}
|
75
|
+
</div>
|
76
|
+
|
77
|
+
<span class="status-label ${bd.status}">${bd.status}</span>
|
78
|
+
|
79
|
+
${bd.status != 'deleted' && html`
|
80
|
+
<${StatusBlock} class="job-status" title="Jobs" ...${bd.jobs} />
|
81
|
+
<${StatusBlock} class="batch-status" title="Batches" ...${bd.batches} />
|
82
|
+
`}
|
83
|
+
</div>
|
84
|
+
</div>
|
85
|
+
|
86
|
+
<div class="subitems ${this.state.collapsed ? 'hidden' : ''}">
|
87
|
+
${sub_entries}
|
88
|
+
${!fully_loaded && load_more_elem}
|
89
|
+
</div>
|
90
|
+
</div>`
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
class TreeRoot extends Component {
|
95
|
+
render() {
|
96
|
+
const tree_data = JSON.parse(document.querySelector('#batch-tree #initial-data').innerHTML);
|
97
|
+
return html`
|
98
|
+
<div class="tree-header">
|
99
|
+
<${StatusBlock} pending_count="pending" failed_count="failed" successful_count="successful" total_count="total" />
|
100
|
+
</div>
|
101
|
+
<${TreeLevel} data=${tree_data} />
|
102
|
+
`;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
render(html`<${TreeRoot} />`, document.querySelector('#batch-tree'));
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
<% add_to_head do %>
|
3
|
+
<meta name="sidekiq-baseurl" content="<%= root_path %>" />
|
4
|
+
<% if dev_mode? %>
|
5
|
+
<link href="<%= root_path %>batches_assets/css/styles.less" media="screen" rel="stylesheet/less" type="text/css" />
|
6
|
+
<script async type="text/javascript" src="https://unpkg.com/less@4.1.1/dist/less.js" data-async="true"></script>
|
7
|
+
<% else %>
|
8
|
+
<link href="<%= root_path %>batches_assets/css/styles.less" media="screen" rel="stylesheet/less" type="text/css" />
|
9
|
+
<script async type="text/javascript" src="https://unpkg.com/less@4.1.1/dist/less.js" data-async="true"></script>
|
10
|
+
<%# TODO: Pre-compile LESS %>
|
11
|
+
<!-- <link href="<%= root_path %>batches_assets/css/styles.css" media="screen" rel="stylesheet" type="text/css" /> -->
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
<%= erb get_template(:_common) %>
|
2
|
+
|
1
3
|
<h3><%= t('Batch') %></h3>
|
2
4
|
<% status = CanvasSync::JobBatches::Batch::Status.new(@batch) %>
|
3
5
|
|
@@ -17,70 +19,13 @@
|
|
17
19
|
<td><%= @batch.description %></td>
|
18
20
|
</tr>
|
19
21
|
<tr>
|
20
|
-
<th colspan="2" scope=row><%= t('
|
22
|
+
<th colspan="2" scope=row><%= t('Context') %></td>
|
21
23
|
<td>
|
22
|
-
<code class="code-wrap">
|
23
|
-
<div class="args-extended"><%= @batch
|
24
|
+
<code class="code-wrap batch-context">
|
25
|
+
<div class="args-extended"><%= format_context(@batch) %></div>
|
24
26
|
</code>
|
25
27
|
</td>
|
26
28
|
</tr>
|
27
|
-
<tr>
|
28
|
-
<th colspan="2" scope=row><%= t('Full Context') %></td>
|
29
|
-
<td>
|
30
|
-
<code class="code-wrap">
|
31
|
-
<div class="args-extended"><%= @batch.context.flatten.to_json %></div>
|
32
|
-
</code>
|
33
|
-
</td>
|
34
|
-
</tr>
|
35
|
-
|
36
|
-
<tr>
|
37
|
-
<th colspan="3">Jobs</th>
|
38
|
-
</tr>
|
39
|
-
<tr>
|
40
|
-
<th></th>
|
41
|
-
<th><%= t('Pending') %></th>
|
42
|
-
<td><%= status.pending %></th>
|
43
|
-
</tr>
|
44
|
-
<tr>
|
45
|
-
<th></th>
|
46
|
-
<th><%= t('Failed') %></th>
|
47
|
-
<td><%= status.failures %></th>
|
48
|
-
</tr>
|
49
|
-
<tr>
|
50
|
-
<th></th>
|
51
|
-
<th><%= t('Complete') %></th>
|
52
|
-
<td><%= status.completed_count %></th>
|
53
|
-
</tr>
|
54
|
-
<tr>
|
55
|
-
<th></th>
|
56
|
-
<th><%= t('Total') %></th>
|
57
|
-
<td><%= status.job_count %></th>
|
58
|
-
</tr>
|
59
|
-
|
60
|
-
<tr>
|
61
|
-
<th colspan="3">Batches</th>
|
62
|
-
</tr>
|
63
|
-
<tr>
|
64
|
-
<th></th>
|
65
|
-
<th><%= t('Pending') %></th>
|
66
|
-
<td><%= status.child_count - status.successful_children_count %></th>
|
67
|
-
</tr>
|
68
|
-
<tr>
|
69
|
-
<th></th>
|
70
|
-
<th><%= t('Failed') %></th>
|
71
|
-
<td><%= status.failed_children_count %></th>
|
72
|
-
</tr>
|
73
|
-
<tr>
|
74
|
-
<th></th>
|
75
|
-
<th><%= t('Success') %></th>
|
76
|
-
<td><%= status.successful_children_count %></th>
|
77
|
-
</tr>
|
78
|
-
<tr>
|
79
|
-
<th></th>
|
80
|
-
<th><%= t('Total') %></th>
|
81
|
-
<td><%= status.child_count %></th>
|
82
|
-
</tr>
|
83
|
-
|
84
29
|
</tbody>
|
85
30
|
</table>
|
86
31
|
</div>
|
@@ -88,51 +33,33 @@
|
|
88
33
|
<header class="row">
|
89
34
|
<div class="col-sm-5">
|
90
35
|
<h3>
|
91
|
-
<%= t('
|
36
|
+
<%= t('Child Batches') %>
|
92
37
|
</h3>
|
93
38
|
</div>
|
94
|
-
<%
|
95
|
-
@current_page = @current_jobs_page
|
96
|
-
@total_size = @total_jobs_size
|
97
|
-
%>
|
98
|
-
<% if @jobs.any? && @total_size > @count.to_i %>
|
99
|
-
<div class="col-sm-4">
|
100
|
-
<%= erb get_template(:_pagination), locals: { url: "#{root_path}batches/#{@batch.bid}", page_key: :job_page } %>
|
101
|
-
</div>
|
102
|
-
<% end %>
|
103
39
|
</header>
|
104
40
|
|
105
|
-
|
106
|
-
<div class="table_container">
|
107
|
-
<%= erb get_template(:_jobs_table), locals: { jobs: @jobs } %>
|
108
|
-
</div>
|
109
|
-
<% end %>
|
41
|
+
<%= erb get_template(:_batch_tree), locals: { } %>
|
110
42
|
|
111
43
|
<header class="row">
|
112
44
|
<div class="col-sm-5">
|
113
45
|
<h3>
|
114
|
-
<%= t('
|
46
|
+
<%= t('Jobs') %>
|
47
|
+
<i>(Queued and Current)</i>
|
115
48
|
</h3>
|
116
49
|
</div>
|
117
50
|
<%
|
118
|
-
@current_page = @
|
119
|
-
@total_size = @
|
51
|
+
@current_page = @current_jobs_page
|
52
|
+
@total_size = @total_jobs_size
|
120
53
|
%>
|
121
|
-
<% if @
|
54
|
+
<% if @jobs.any? && @total_size > @count.to_i %>
|
122
55
|
<div class="col-sm-4">
|
123
|
-
<%= erb get_template(:_pagination), locals: { url: "#{root_path}batches/#{@batch.bid}", page_key: :
|
56
|
+
<%= erb get_template(:_pagination), locals: { url: "#{root_path}batches/#{@batch.bid}", page_key: :job_page } %>
|
124
57
|
</div>
|
125
58
|
<% end %>
|
126
59
|
</header>
|
127
60
|
|
128
|
-
<% if @
|
61
|
+
<% if @jobs.any? %>
|
129
62
|
<div class="table_container">
|
130
|
-
<%= erb get_template(:
|
63
|
+
<%= erb get_template(:_jobs_table), locals: { jobs: @jobs } %>
|
131
64
|
</div>
|
132
65
|
<% end %>
|
133
|
-
|
134
|
-
<form class="form-horizontal" action="<%= root_path %>batches/<%= @batch.bid %>" method="post">
|
135
|
-
<%= csrf_tag %>
|
136
|
-
<a class="btn btn-default" href="<%= root_path %>batches"><%= t('GoBack') %></a>
|
137
|
-
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
|
138
|
-
</form>
|
@@ -9,11 +9,19 @@ require_relative "web/helpers"
|
|
9
9
|
|
10
10
|
module CanvasSync::JobBatches::Sidekiq
|
11
11
|
module Web
|
12
|
+
DEV_MODE = (defined?(Rails) && !Rails.env.production?) || !!ENV["SIDEKIQ_WEB_TESTING"]
|
13
|
+
|
12
14
|
def self.registered(app) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
13
15
|
app.helpers do
|
14
16
|
include Web::Helpers
|
17
|
+
|
18
|
+
def dev_mode?
|
19
|
+
DEV_MODE
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
23
|
+
# =============== BATCHES =============== #
|
24
|
+
|
17
25
|
app.get "/batches" do
|
18
26
|
@count = (params['count'] || 25).to_i
|
19
27
|
@current_page, @total_size, @batches = page('batches', params['page'], @count)
|
@@ -26,6 +34,8 @@ module CanvasSync::JobBatches::Sidekiq
|
|
26
34
|
@bid = params[:bid]
|
27
35
|
@batch = CanvasSync::JobBatches::Batch.new(@bid)
|
28
36
|
|
37
|
+
@tree_data = tree_data(@bid)
|
38
|
+
|
29
39
|
@count = (params['count'] || 25).to_i
|
30
40
|
@current_batches_page, @total_batches_size, @sub_batches = page("BID-#{@batch.bid}-bids", params['batch_page'], @count)
|
31
41
|
@sub_batches = @sub_batches.map {|b, score| CanvasSync::JobBatches::Batch.new(b) }
|
@@ -36,6 +46,81 @@ module CanvasSync::JobBatches::Sidekiq
|
|
36
46
|
erb(get_template(:batch))
|
37
47
|
end
|
38
48
|
|
49
|
+
app.get "/batches/:bid/tree" do
|
50
|
+
@bid = params[:bid]
|
51
|
+
|
52
|
+
json(tree_data(@bid, slice: params[:slice]))
|
53
|
+
end
|
54
|
+
|
55
|
+
app.helpers do
|
56
|
+
def tree_data(root_bid, slice: nil)
|
57
|
+
tree_bids = CanvasSync::JobBatches::Batch.bid_hierarchy(root_bid, slice: slice)
|
58
|
+
|
59
|
+
CanvasSync::JobBatches::Batch.redis do |r|
|
60
|
+
layer_data = ->(layer, parent = nil) {
|
61
|
+
bid = layer[0]
|
62
|
+
batch = CanvasSync::JobBatches::Batch.new(bid)
|
63
|
+
|
64
|
+
jobs_total = r.hget("BID-#{bid}", "job_count").to_i
|
65
|
+
jobs_pending = r.hget("BID-#{bid}", 'pending').to_i
|
66
|
+
jobs_failed = r.scard("BID-#{bid}-failed").to_i
|
67
|
+
jobs_success = jobs_total - jobs_pending
|
68
|
+
|
69
|
+
batches_total = r.hget("BID-#{bid}", 'children').to_i
|
70
|
+
batches_success = r.scard("BID-#{bid}-batches-success").to_i
|
71
|
+
batches_pending = batches_total - batches_success
|
72
|
+
batches_failed = r.scard("BID-#{bid}-batches-failed").to_i
|
73
|
+
|
74
|
+
status = 'in_progress'
|
75
|
+
status = 'complete' if batches_pending == batches_failed && jobs_pending == jobs_failed
|
76
|
+
status = 'success' if batches_pending == 0 && jobs_pending == 0
|
77
|
+
status = 'deleted' if bid != root_bid && !batch.parent_bid
|
78
|
+
|
79
|
+
{
|
80
|
+
bid: bid,
|
81
|
+
created_at: r.hget("BID-#{bid}", 'created_at'),
|
82
|
+
status: status,
|
83
|
+
parent_bid: parent ? parent.bid : batch.parent_bid,
|
84
|
+
description: batch.description,
|
85
|
+
jobs: {
|
86
|
+
pending_count: jobs_pending,
|
87
|
+
successful_count: jobs_success,
|
88
|
+
failed_count: jobs_failed,
|
89
|
+
total_count: jobs_total,
|
90
|
+
# items: batches.map{|b| layer_data[b] },
|
91
|
+
},
|
92
|
+
batches: {
|
93
|
+
pending_count: batches_pending,
|
94
|
+
successful_count: batches_success,
|
95
|
+
failed_count: batches_failed,
|
96
|
+
total_count: batches_total,
|
97
|
+
items: layer[1].map{|b| layer_data[b, batch] },
|
98
|
+
},
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
data = layer_data[tree_bids]
|
103
|
+
data[:batches][:slice] = slice if slice
|
104
|
+
data
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def format_context(batch)
|
109
|
+
bits = []
|
110
|
+
own_keys = batch.context.own.keys
|
111
|
+
batch.context.flatten.each do |k,v|
|
112
|
+
added = own_keys.include? k
|
113
|
+
bits << " <span class=\"key #{added ? 'own' : 'inherited'}\">\"#{k}\": #{v.to_json},</span>"
|
114
|
+
end
|
115
|
+
bits = [
|
116
|
+
"{ // <span class=\"own\">Added</span> / <span class=\"inherited\">Inherited</span>",
|
117
|
+
*bits,
|
118
|
+
'}'
|
119
|
+
]
|
120
|
+
bits.join("\n")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
39
124
|
app.post "/batches/all" do
|
40
125
|
if params['delete']
|
41
126
|
drain_zset('batches') do |batches|
|
@@ -107,6 +192,14 @@ module CanvasSync::JobBatches::Sidekiq
|
|
107
192
|
end
|
108
193
|
|
109
194
|
if defined?(::Sidekiq::Web)
|
195
|
+
rules = []
|
196
|
+
rules = [[:all, {"Cache-Control" => "public, max-age=86400"}]] unless CanvasSync::JobBatches::Sidekiq::Web::DEV_MODE
|
197
|
+
|
198
|
+
::Sidekiq::Web.use Rack::Static, urls: ["/batches_assets"],
|
199
|
+
root: File.expand_path("#{File.dirname(__FILE__)}/web"),
|
200
|
+
cascade: true,
|
201
|
+
header_rules: rules
|
202
|
+
|
110
203
|
::Sidekiq::Web.register CanvasSync::JobBatches::Sidekiq::Web
|
111
204
|
::Sidekiq::Web.tabs["Batches"] = "batches"
|
112
205
|
::Sidekiq::Web.tabs["Pools"] = "pools"
|
@@ -46,7 +46,7 @@ module CanvasSync
|
|
46
46
|
m = Regexp.last_match
|
47
47
|
day = m[1]
|
48
48
|
skip = m[2] || "1"
|
49
|
-
|
49
|
+
DateTime.now.send(:"#{day}?") && last_full_sync.end_of_day <= (skip.to_i.weeks.ago.end_of_day)
|
50
50
|
when opt.match?(%r{^(\d+)\%$})
|
51
51
|
m = Regexp.last_match
|
52
52
|
rand(100) < m[1].to_i
|
@@ -4,8 +4,9 @@ module CanvasSync
|
|
4
4
|
# Re-enqueues itself if the report is still processing on Canvas.
|
5
5
|
# Enqueues the ReportProcessor when the report has completed.
|
6
6
|
class ReportChecker < CanvasSync::Job
|
7
|
-
REPORT_TIMEOUT =
|
7
|
+
REPORT_TIMEOUT = 24.hours
|
8
8
|
COMPILATION_TIMEOUT = 1.hour
|
9
|
+
MAX_TRIES = 3
|
9
10
|
|
10
11
|
# @param report_name [Hash] e.g., 'provisioning_csv'
|
11
12
|
# @param report_id [Integer]
|
@@ -13,6 +14,7 @@ module CanvasSync
|
|
13
14
|
# @param options [Hash] hash of options that will be passed to the job processor
|
14
15
|
# @return [nil]
|
15
16
|
def perform(report_name, report_id, processor, options, checker_context = {}) # rubocop:disable Metrics/AbcSize
|
17
|
+
max_tries = options[:report_max_tries] || batch_context[:report_max_tries] || MAX_TRIES
|
16
18
|
account_id = options[:account_id] || batch_context[:account_id] || "self"
|
17
19
|
report_status = CanvasSync.get_canvas_sync_client(batch_context)
|
18
20
|
.report_status(account_id, report_name, report_id)
|
@@ -27,9 +29,17 @@ module CanvasSync
|
|
27
29
|
report_id,
|
28
30
|
)
|
29
31
|
when "error", "deleted"
|
30
|
-
|
32
|
+
checker_context[:failed_attempts] ||= 0
|
33
|
+
checker_context[:failed_attempts] += 1
|
34
|
+
failed_attempts = checker_context[:failed_attempts]
|
35
|
+
message = "Report failed to process; status was #{report_status} for report_name: #{report_name}, report_id: #{report_id}, #{current_organization.name}. This report has now failed #{checker_context[:failed_attempts]} time." # rubocop:disable Metrics/LineLength
|
31
36
|
Rails.logger.error(message)
|
32
|
-
|
37
|
+
if failed_attempts >= max_tries
|
38
|
+
Rails.logger.error("This report has failed #{failed_attempts} times. Giving up.")
|
39
|
+
raise message
|
40
|
+
else
|
41
|
+
restart_report(options, report_name, processor, checker_context)
|
42
|
+
end
|
33
43
|
else
|
34
44
|
report_timeout = parse_timeout(options[:report_timeout] || batch_context[:report_timeout] || REPORT_TIMEOUT)
|
35
45
|
if timeout_met?(options[:sync_start_time], report_timeout)
|
@@ -51,7 +61,7 @@ module CanvasSync
|
|
51
61
|
report_id,
|
52
62
|
processor,
|
53
63
|
options,
|
54
|
-
checker_context
|
64
|
+
checker_context
|
55
65
|
)
|
56
66
|
end
|
57
67
|
end
|
@@ -66,6 +76,29 @@ module CanvasSync
|
|
66
76
|
def parse_timeout(val)
|
67
77
|
val
|
68
78
|
end
|
79
|
+
|
80
|
+
def restart_report(options, report_name, processor, checker_context)
|
81
|
+
account_id = options[:account_id] || batch_context[:account_id] || "self"
|
82
|
+
options[:sync_start_time] = DateTime.now.utc.iso8601
|
83
|
+
new_context = {}
|
84
|
+
new_context[:failed_attempts] = checker_context[:failed_attempts]
|
85
|
+
report_id = start_report(account_id, report_name, options[:report_params])
|
86
|
+
CanvasSync::Jobs::ReportChecker
|
87
|
+
.set(wait: report_checker_wait_time)
|
88
|
+
.perform_later(
|
89
|
+
report_name,
|
90
|
+
report_id,
|
91
|
+
processor,
|
92
|
+
options,
|
93
|
+
new_context
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def start_report(account_id, report_name, report_params)
|
98
|
+
report = CanvasSync.get_canvas_sync_client(batch_context)
|
99
|
+
.start_report(account_id, report_name, report_params)
|
100
|
+
report["id"]
|
101
|
+
end
|
69
102
|
end
|
70
103
|
end
|
71
104
|
end
|