make fewer trips to the db for report runners

we still don’t want to send a giant batch so this
will limit based off the number of ids being sent

refs CORE-2742

test plan
 - specs should pass

Change-Id: Ife00367d818a48a9934b4f224eb865c20292dd31
Reviewed-on: https://gerrit.instructure.com/188807
Tested-by: Jenkins
Reviewed-by: James Williams <jamesw@instructure.com>
QA-Review: James Williams <jamesw@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
This commit is contained in:
Rob Orton 2019-04-08 22:16:13 -06:00
parent 47a4974528
commit 09b38f8151
3 changed files with 50 additions and 0 deletions

View File

@ -29,6 +29,24 @@ class AccountReport < ActiveRecord::Base
serialize :parameters
attr_accessor :runners
def initialize(*)
@runners = []
super
end
def add_report_runner(batch)
@runners ||= []
runners << self.account_report_runners.new(batch_items: batch, created_at: Time.zone.now, updated_at: Time.zone.now)
end
def write_report_runners
return if runners.empty?
self.class.bulk_insert_objects(runners)
@runners = []
end
workflow do
state :created
state :running

View File

@ -316,6 +316,19 @@ module AccountReports::ReportHelper
[[item_count/100.to_f.round(0), min].max, max].min
end
def create_report_runners(ids, total, min: 25, max: 1000)
ids_so_far = 0
ids.each_slice(number_of_items_per_runner(total, min: min, max: max)) do |batch|
@account_report.add_report_runner(batch)
ids_so_far += batch.length
if ids_so_far >= Setting.get("ids_per_report_runner_batch", 10_000).to_i
@account_report.write_report_runners
ids_so_far = 0
end
end
@account_report.write_report_runners
end
def run_account_report_runner(report_runner, headers)
return if report_runner.reload.workflow_state == 'aborted'
@account_report = report_runner.account_report

View File

@ -42,6 +42,25 @@ describe "report helper" do
expect(report.number_of_items_per_runner(109213081, max: 100)).to eq 100
end
it 'should create report runners with a single trip' do
account_report.save!
expect(AccountReport).to receive(:bulk_insert_objects).once.and_call_original
report.create_report_runners((1..50).to_a, 50)
expect(account_report.account_report_runners.count).to eq 2
end
it 'should create report runners with few trips to the db' do
account_report.save!
# lower the setting so we can do more than one trip with less data
Setting.set("ids_per_report_runner_batch", 1_000)
# once with 1_008 ids and 84 runners and then once with 200 ids and the
# other runners
expect(AccountReport).to receive(:bulk_insert_objects).twice.and_call_original
# also got to pass min so that we get runners with 12 ids instead of 25
report.create_report_runners((1..1_200).to_a, 1_200, min: 10)
expect(account_report.account_report_runners.count).to eq 100
end
describe "#send_report" do
before do
allow(AccountReports).to receive(:available_reports).and_return(account_report.report_type => {title: 'test_report'})