Skip to content

Commit

Permalink
fix: fix performance issue loading latest version for pacticipant
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Nov 30, 2021
1 parent 6ae6463 commit c575d13
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 23 deletions.
38 changes: 36 additions & 2 deletions lib/pact_broker/domain/pacticipant.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
require "pact_broker/db"
require "pact_broker/messages"
require "pact_broker/repositories/helpers"
require "pact_broker/versions/latest_version"
require "pact_broker/domain/label"
require "pact_broker/string_refinements"
require "pact_broker/pacticipants/generate_display_name"

module PactBroker
module Domain
class LatestVersionForPacticipantEagerLoader
def self.call(eo, **_other)
populate_associations(eo[:rows])
end

def self.populate_associations(pacticipants)
pacticipants.each { | pacticipant | pacticipant.associations[:latest_version] = nil }
pacticipant_ids = pacticipants.collect(&:id)

max_orders = PactBroker::Domain::Version
.where(pacticipant_id: pacticipant_ids)
.select_group(:pacticipant_id)
.select_append { max(order).as(latest_order) }

max_orders_join = {
Sequel[:max_orders][:latest_order] => Sequel[:versions][:order],
Sequel[:max_orders][:pacticipant_id] => Sequel[:versions][:pacticipant_id]
}

latest_versions = PactBroker::Domain::Version
.select_all_qualified
.join(max_orders, max_orders_join, { table_alias: :max_orders})

latest_versions.each do | version |
pacticipant = pacticipants.find{ | pacticipant | pacticipant.id == version.pacticipant_id }
pacticipant.associations[:latest_version] = version
end
end
end

class Pacticipant < Sequel::Model

include Messages
include PactBroker::Pacticipants::GenerateDisplayName
using PactBroker::StringRefinements
Expand All @@ -21,7 +51,11 @@ class Pacticipant < Sequel::Model
one_to_many :versions, :order => :order, :reciprocal => :pacticipant
one_to_many :labels, :order => :name, :reciprocal => :pacticipant
one_to_many :pacts
one_to_one :latest_version, :class => "PactBroker::Versions::LatestVersion", primary_key: :id, key: :pacticipant_id
one_to_one :latest_version, :class => "PactBroker::Domain::Version",
primary_key: :id, key: :pacticipant_id,
dataset: lambda { PactBroker::Domain::Version.where(pacticipant_id: id).order(Sequel.desc(:order)).limit(1) },
eager_loader: LatestVersionForPacticipantEagerLoader

one_to_many :branch_heads, class: "PactBroker::Versions::BranchHead", primary_key: :id, key: :pacticipant_id
one_to_many :branches, class: "PactBroker::Versions::Branch", primary_key: :id, key: :pacticipant_id

Expand Down
21 changes: 0 additions & 21 deletions lib/pact_broker/versions/latest_version.rb

This file was deleted.

32 changes: 32 additions & 0 deletions spec/lib/pact_broker/domain/pacticipant_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require "pact_broker/domain/pacticipant"

module PactBroker
module Domain
describe Pacticipant do
describe "#latest_version" do
before do
td.create_consumer("Foo")
.create_consumer_version("1")
.create_consumer_version("2")
.create_consumer_version("3")
.create_consumer("Bar")
.create_consumer_version("10")
.create_consumer_version("11")
.create_consumer_version("12")
end

it "lazy loads" do
pacticipants = Pacticipant.order(:id).all
expect(pacticipants.first.latest_version.number).to eq "3"
expect(pacticipants.last.latest_version.number).to eq "12"
end

it "eager_loads" do
pacticipants = Pacticipant.order(:id).eager(:latest_version).all
expect(pacticipants.first.associations[:latest_version].number).to eq "3"
expect(pacticipants.last.associations[:latest_version].number).to eq "12"
end
end
end
end
end

0 comments on commit c575d13

Please sign in to comment.