Refactor proxy order syncer using direct sql query for increased speed

This commit is contained in:
Rob Harrington
2017-11-15 12:14:19 +11:00
parent 48b39f4712
commit 146348a4fe
2 changed files with 35 additions and 8 deletions

View File

@@ -17,7 +17,8 @@ module OpenFoodNetwork
def sync!
return sync_all! if @standing_orders
initialise_proxy_orders!
return initialise_proxy_orders! unless @standing_order.id
create_proxy_orders!
remove_obsolete_proxy_orders!
end
@@ -26,7 +27,7 @@ module OpenFoodNetwork
def sync_all!
@standing_orders.each do |standing_order|
@standing_order = standing_order
initialise_proxy_orders!
create_proxy_orders!
remove_obsolete_proxy_orders!
end
end
@@ -37,6 +38,15 @@ module OpenFoodNetwork
end
end
def create_proxy_orders!
return unless not_closed_in_range_order_cycles.any?
query = "INSERT INTO proxy_orders (standing_order_id, order_cycle_id, updated_at, created_at)"
query << " VALUES #{insert_values}"
query << " ON CONFLICT DO NOTHING"
ActiveRecord::Base.connection.exec_query(query)
end
def uninitialised_order_cycle_ids
not_closed_in_range_order_cycles.pluck(:id) - proxy_orders.map(&:order_cycle_id)
end
@@ -51,6 +61,13 @@ module OpenFoodNetwork
proxy_orders.where('order_cycle_id NOT IN (?)', in_range_order_cycle_ids)
end
def insert_values
now = Time.now.utc.iso8601
not_closed_in_range_order_cycles
.map{ |oc| "(#{standing_order.id},#{oc.id},'#{now}','#{now}')" }
.join(",")
end
def not_closed_in_range_order_cycles
in_range_order_cycles.merge(OrderCycle.not_closed)
end

View File

@@ -6,8 +6,8 @@ module OpenFoodNetwork
let!(:standing_order) { create(:standing_order) }
it "raises an error when initialized with an object that is not a StandingOrder or an ActiveRecord::Relation" do
expect{ProxyOrderSyncer.new(standing_order)}.to_not raise_error RuntimeError
expect{ProxyOrderSyncer.new(StandingOrder.where(id: standing_order.id))}.to_not raise_error RuntimeError
expect{ProxyOrderSyncer.new(standing_order)}.to_not raise_error
expect{ProxyOrderSyncer.new(StandingOrder.where(id: standing_order.id))}.to_not raise_error
expect{ProxyOrderSyncer.new("something")}.to raise_error RuntimeError
end
end
@@ -31,8 +31,8 @@ module OpenFoodNetwork
let!(:po2) { create(:proxy_order, standing_order: standing_order, order_cycle: oc7) }
let!(:po3) { create(:proxy_order, standing_order: standing_order, order_cycle: oc8) }
it "performs both initialise and remove actions to rectify proxy orders" do
expect(syncer).to receive(:initialise_proxy_orders!).and_call_original
it "performs both create and remove actions to rectify proxy orders" do
expect(syncer).to receive(:create_proxy_orders!).and_call_original
expect(syncer).to receive(:remove_obsolete_proxy_orders!).and_call_original
syncer.sync!
standing_order.reload
@@ -44,9 +44,19 @@ module OpenFoodNetwork
end
describe "#initialise_proxy_orders!" do
it "adds proxy orders for in-range order cycles that are not already closed" do
let(:new_standing_order) { build(:standing_order, schedule: schedule, begins_at: now + 1.minute, ends_at: now + 2.minutes) }
it "builds proxy orders for in-range order cycles that are not already closed" do
allow(syncer).to receive(:standing_order) { new_standing_order }
expect{syncer.send(:initialise_proxy_orders!)}.to_not change(ProxyOrder, :count).from(0)
expect{new_standing_order.save!}.to change(ProxyOrder, :count).from(0).to(2)
expect(new_standing_order.proxy_orders.map(&:order_cycle_id)).to include oc3.id, oc4.id
end
end
describe "#create_proxy_orders!" do
it "creates proxy orders for in-range order cycles that are not already closed" do
allow(syncer).to receive(:standing_order) { standing_order }
expect{syncer.send(:initialise_proxy_orders!)}.to change(ProxyOrder, :count).from(0).to(2)
expect{syncer.send(:create_proxy_orders!)}.to change(ProxyOrder, :count).from(0).to(2)
expect(standing_order.proxy_orders.map(&:order_cycle)).to include oc3, oc4
end
end